Différence entre public, privé et protégé de l'héritage
Quelle est la différence entre public
, private
, et protected
l'héritage en C++? Toutes les questions que j'ai trouvé sur AFIN de traiter certains cas particuliers.
Vous devez vous connecter pour publier un commentaire.
De répondre à cette question, j'aimerais décrire membre du accesseurs en premier dans mes propres mots. Si vous le savez déjà, passez à la rubrique "suivant:".
Il y a trois accesseurs que je suis au courant:
public
,protected
etprivate
.Laisser:
Base
est également conscient du fait queBase
contientpublicMember
.Base
contientprotectedMember
.Base
est conscient deprivateMember
.Par "est au courant de", je veux dire "reconnaître l'existence d', et ainsi être en mesure d'accéder à".
suivante:
La même chose arrive avec le public, le privé et protégé de l'héritage. Considérons une classe
Base
et une classeChild
qui hérite deBase
.public
, tout ce qui est conscient deBase
etChild
est également conscient du fait queChild
hérite deBase
.protected
, seulementChild
, et ses enfants sont conscients qu'ils héritent deBase
.private
, personne d'autre queChild
est conscient de l'héritage.SomeBase
est juste comme une codé en dur de manière à composer un membre anonyme de typeSomeBase
. Cela, comme n'importe quel autre membre, dispose d'un accès prescripteur, qui exerce le même contrôle sur l'accès externe.private
.protected
déclarations de la classe de base accessible au descendant objet, pas de la classe:struct Base { protected: int x; }; struct Desc : Base { Desc(Base& b) { (void)b.x; } };
ne parvient pas à compiler.Derived::SomeBase
REMARQUE IMPORTANTE: les Classes B, C et D contiennent toutes les variables x, y et z. Il est juste question de l'accès.
Propos de l'utilisation de protégé et privé de l'héritage vous avez pu lire ici.
Limiter la visibilité de la succession dont le code est pas capable de voir qu'une classe hérite d'une autre classe: les conversions Implicites de la dérivée de la base ne fonctionne pas, et
static_cast
à partir de la base de la dérivée ne fonctionne pas, soit.Seuls les membres/amis d'une classe peut voir privé de l'héritage, et seuls les membres/amis et les classes dérivées peuvent voir les protégés de l'héritage.
public héritage
EST-UN héritage. Un bouton-une fenêtre, et partout où une fenêtre est nécessaire, un bouton peut être passé trop.
protégé héritage
Protégés mis en œuvre-en-termes-de. Rarement utile. Utilisé dans
boost::compressed_pair
de dériver de vide de classes et d'économiser de la mémoire à l'aide de vide de la classe de base de l'optimisation (exemple ci-dessous n'utilise pas de modèle de continuer à être au point):privé héritage
Mis en œuvre-en-termes-de. L'utilisation de la classe de base est uniquement pour la mise en œuvre de la classe dérivée. Utile avec les traits et si les sujets de taille (vide traits qui ne contiennent que des fonctions de faire usage de la vide de la classe de base de l'optimisation). Souvent de confinement est la meilleure solution. La taille des chaînes est critique, il est donc souvent vu usage ici
public membre
Globale
Accesseurs
protégé membre
L'amélioration de l'accès pour les classes dérivées
privé membre
Garder les détails de mise en œuvre
Noter que les C-style jette délibérément permet de lancer une classe dérivée d'une protected ou private de la classe de base dans une manière sûre et à jeter dans l'autre sens aussi. Cela doit être évité à tous les frais, car il peut rendre le code dépend de détails de mise en œuvre - mais si nécessaire, vous pouvez faire usage de cette technique.
Il a à voir avec la façon dont les membres publics de la classe de base sont exposés à partir de la classe dérivée.
Comme litb souligne, publique est l'héritage de l'héritage traditionnel, que vous voyez dans la plupart des langages de programmation. Qu'en est-il des modèles de type "EST-UN" de la relation. Privé de l'héritage, autant que je sache quelque chose de particulier pour C++, est un "mis en œuvre EN TERMES DE" relation". Qu'est que vous voulez utilisation l'interface publique de la classe dérivée, mais ne voulez pas que l'utilisateur de la classe dérivée a accès à cette interface. Beaucoup soutiennent que, dans ce cas, vous devez regrouper la classe de base, qui est au lieu d'avoir la classe de base comme un privé, faire en un membre de la dérivée pour la réutilisation de la classe de base de la fonctionnalité.
Ces trois mots-clés sont également utilisés dans un contexte totalement différent de spécifier le visibilité modèle d'héritage.
Ce tableau regroupe toutes les combinaisons possibles de la composante de la déclaration et de l'héritage du modèle de présentation de l'résultant de l'accès aux composants lorsque le sous-classe est complètement défini.
Le tableau ci-dessus est interprété de la manière suivante (jetez un oeil à la première ligne):
Un exemple:
L'résultant de l'accès pour les variables
p
,q
,r
dans la classe Subsub est aucun.L'résultant de l'accès pour les variables
y
,z
dans la classe Sous est protégé et pour la variablex
est aucun.Maintenant permet de définir une sous-classe:
De la catégorie définie nommé Sous laquelle est une sous-classe de la classe nommée
Super
ou queSub
classe est dérivée de laSuper
classe.Le
Sub
classe introduit ni de nouvelles variables, ni de nouvelles fonctions. Ça veut dire que n'importe quel objet de laSub
classe hérite de toutes les caractéristiques après laSuper
la classe qui est en fait une copie d'unSuper
de la classe des objets?Pas. Il n'a pas.
Si nous compiler le code suivant, nous n'obtiendrez rien, mais des erreurs de compilation en disant que
put
etget
méthodes sont inaccessibles. Pourquoi?Lorsque nous omettons la visibilité prescripteur, le compilateur suppose que nous allons appliquer la soi-disant privé de l'héritage. Cela signifie que tous les public superclasse composants transformer en privé accès, privé de la superclasse des composants ne sera pas accessible à tous. Cela signifie donc que vous n'êtes pas autorisé à utiliser ce dernier à l'intérieur de la sous-classe.
Nous informer le compilateur que nous voulons préserver la politique d'accès.
Objets de la
Sub
classe peut faire "presque" les mêmes choses que leurs frères et sœurs plus âgés créé à partir de laSuper
classe. "Presque" parce que le fait d'être une sous-classe signifie également que le classe perdu l'accès privé pour les composants de la super-classe. On ne peut pas écrire une fonction membre de laSub
classe qui serait capable de manipuler directement le stockage variable.C'est une très grave restriction. Est-il une solution de contournement?
Oui.
Le troisième niveau d'accès est appelé protégé. Le mot-clé protégé signifie que le composant marqué avec elle se comporte comme un établissement public lorsqu'il est utilisé par aucune des sous-classes et ressemble à un privé pour le reste du monde. -- C'est vrai que pour le public hérité de classes (comme la Super-classe dans notre exemple) --
Comme vous le voyez dans l'exemple de code que nous avons une nouvelle fonctionnalité à l'
Sub
classe et il fait une chose importante: il accède à la variable de la classe Super.Il ne serait pas possible si la variable a été déclarée à titre privé.
Dans la fonction principale de la portée de la variable qui reste caché de toute façon donc si vous écrivez quelque chose comme:
Le compilateur va vous informer qu'il est un
error: 'int Super::storage' is protected
.Enfin, le dernier programme produira la sortie suivante:
Héritage type : Objet hérité comme:
1) Patrimoine Public:
un. Les membres privés de la classe de Base ne sont pas accessibles dans la classe Dérivée.
b. Des membres protégés de la classe de Base restent protégés dans la classe Dérivée.
c. Les membres publics de la classe de Base restent dans le domaine public dans la classe Dérivée.
Ainsi, d'autres classes peuvent utiliser les membres publics de la classe de Base par le biais objet de classe Dérivée.
2), À L'Abri De L'Héritage:
un. Les membres privés de la classe de Base ne sont pas accessibles dans la classe Dérivée.
b. Des membres protégés de la classe de Base restent protégés dans la classe Dérivée.
c. Les membres publics de la classe de Base deviennent les membres protégés de la classe Dérivée.
Donc, les autres classes ne peuvent pas utiliser les membres publics de la classe de Base par le biais de Dérivés de la classe de l'objet; mais ils sont disponibles à la sous-classe des Dérivés.
3) Privé De L'Héritage:
un. Les membres privés de la classe de Base ne sont pas accessibles dans la classe Dérivée.
b. Protégé & les membres publics de la classe de Base deviennent des membres privés de la classe Dérivée.
Ainsi, aucun des membres de la classe de Base peut être consulté par d'autres classes, par objet de classe Dérivée comme ils sont privés dans la classe Dérivée. Donc, même sous-classe de la Dérivée
la classe ne peuvent pas y accéder.
Public de l'héritage des modèles d'une relation " EST-UN. Avec
chaque
D
est unB
.Privé de l'héritage des modèles EST mis en œuvre-à l'AIDE de la relation (ou ce qui est appelé). Avec
un
D
est pas unB
, mais chaqueD
utilise sonB
dans sa mise en œuvre. Privé de l'héritage peut toujours être éliminé par l'utilisation de confinement à la place:Ce
D
, trop, peut être mis en œuvre à l'aide deB
, dans ce cas, à l'aide de sonb_
. Le confinement est un moins le couplage entre les types de succession, donc en général, il doit être préféré. Parfois l'utilisation d'un contenant, au lieu de privé de l'héritage n'est pas aussi pratique que privé de l'héritage. Souvent, c'est une piètre excuse pour être paresseux.Je ne pense pas que quelqu'un sait de quoi
protected
l'héritage des modèles. Au moins, je n'ai pas vu d'explication convaincante encore.D
dérive privé deD
, il peut remplacer des fonctions virtuelles deB
. (Si, par exemple,B
est un observateur de l'interface, puisD
pourrait mettre en œuvre et de transmettrethis
pour les fonctions nécessitant auch une interface, sans tout le monde d'être en mesure d'utiliserD
en tant qu'observateur.) Aussi,D
de façon sélective les membres deB
disponible dans son interface en faisantusing B::member
. Les deux sont syntaxiquement peu pratique à mettre en œuvre lorsque lesB
est membre.protected
l'héritage que j'ai trouvé utile avec unvirtual
de la classe de base etprotected
ctor:struct CommonStuff { CommonStuff(Stuff*) {/* assert !=0 */ } }; struct HandlerMixin1 : protected virtual CommonStuff { protected: HandlerMixin1() : CommonStuff(nullptr) {} /*...*/ }; struct Handler : HandlerMixin1, ... { Handler(Stuff& stuff) : CommonStuff(&stuff) {} };
Si vous héritez d'un public d'une autre classe, tout le monde sait que vous êtes héritent et vous pouvez être utilisé polymorphically par une personne au moyen d'une base de pointeur de classe.
Si vous héritez protectedly seulement vos enfants des classes sera capable de l'utiliser vous polymorphically.
Si vous héritez en privé seulement vous serez en mesure d'exécuter les méthodes de la classe parent.
Qui, fondamentalement, symbolise la connaissance du reste de la classe au sujet de votre relation avec votre classe parent
Protégé par les membres de données peut être consulté par toutes les classes qui héritent de la classe. Les données privées des membres, cependant, ne peut pas. Disons que nous avons les éléments suivants:
De l'intérieur de votre extension de cette classe, référencement
this.myPrivateMember
ne fonctionne pas. Cependant,this.myProtectedMember
volonté. La valeur est toujours encapsulé, donc si nous avons une instanciation de cette classe appeléemyObj
, puismyObj.myProtectedMember
ne fonctionne pas, de sorte qu'il est similaire en fonction d'une donnée membre privée.Résumé:
Lorsque vous héritez, vous pouvez (dans certaines langues) changer le type de protection d'un membre de données dans certaine direction, par exemple, de protection du public.
Basé sur cette exemple pour java... je pense à une petite table, une image vaut mille mots 🙂
Privé:
Les membres privés d'une classe de base ne peut être accessible que par les membres de la classe de base .
Public:
Le public et les membres d'une classe de base peut être consulté par les membres de la classe de base, les membres de sa classe dérivée ainsi que les membres qui sont en dehors de la classe de base et la classe dérivée.
Protégé:
Les membres protégés de la classe de base peut être consulté par les membres de la classe de base ainsi que les membres de sa classe dérivée.
En bref:
privé: base
protégé: base + dérivés
public: base + dérivé + tout autre membre
J'ai trouvé une réponse facile et donc pensé à le poster pour l'avenir de ma référence trop.
Son à partir des liens http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/
C'est essentiellement la protection de l'accès du public et des membres protégés de la classe de base dans la classe dérivée. Avec le service public de l'héritage, la classe dérivée peut voir le public et les membres protégés de la base. Avec privé de l'héritage, il ne peut pas. Protégée, la classe dérivée et de toutes les classes dérivées de qui peut les voir.