Pour répondre à cette question, j'aimerais d'abord décrire les accesseurs des membres dans mes propres mots. Si vous le savez déjà, passez à la rubrique "suivant:".
Il y a trois accesseurs que je connais: public
, protected
et private
.
Laisser:
class Base {
public:
int publicMember;
protected:
int protectedMember;
private:
int privateMember;
};
- Tout ce qui est conscient
Base
est également conscient de ce qui Base
contient publicMember
.
- Seuls les enfants (et leurs enfants) savent que
Base
contient protectedMember
.
- Personne mais
Base
n'est au courant privateMember
.
Par "est au courant de", je veux dire "reconnaître l'existence de, et donc pouvoir y accéder".
suivant:
La même chose se produit avec l'héritage public, privé et protégé. Prenons une classe Base
et une classe Child
qui hérite de Base
.
- Si l'héritage est
public
, tout ce qui est conscient Base
et qui Child
est également conscient de ce qui Child
hérite Base
.
- Si l'héritage est
protected
, seulement Child
, et ses enfants, sont conscients qu'ils héritent de Base
.
- Si l'héritage est
private
, personne d'autre que lui Child
n'est au courant de l'héritage.
SomeBase
est comme une façon codée en dur de composer un membre anonyme de typeSomeBase
. Celui-ci, comme tout autre membre, possède un spécificateur d'accès, qui exerce le même contrôle sur l'accès externe.REMARQUE IMPORTANTE: les classes B, C et D contiennent toutes les variables x, y et z. C'est juste une question d'accès.
À propos de l'utilisation de l'héritage protégé et privé, vous pouvez lire ici .
la source
Limiter la visibilité de l'héritage rendra le code incapable de voir que certaines classes héritent d'une autre classe: les conversions implicites du dérivé vers la base ne fonctionneront pas, et
static_cast
de la base vers le dérivé ne fonctionneront pas non plus.Seuls les membres / amis d'une classe peuvent voir l'héritage privé, et seuls les membres / amis et les classes dérivées peuvent voir l'héritage protégé.
héritage public
Héritage IS-A. Un bouton est une fenêtre, et partout où une fenêtre est nécessaire, un bouton peut également être transmis.
héritage protégé
Protégé mis en œuvre en termes de. Rarement utile. Utilisé
boost::compressed_pair
pour dériver de classes vides et économiser de la mémoire en utilisant l'optimisation de classe de base vide (l'exemple ci-dessous n'utilise pas de modèle pour rester au point):héritage privé
Mis en œuvre en termes de. L'utilisation de la classe de base est uniquement destinée à l'implémentation de la classe dérivée. Utile avec les traits et si la taille est importante (les traits vides qui ne contiennent que des fonctions utiliseront l'optimisation de classe de base vide). Cependant, le confinement est souvent la meilleure solution. La taille des chaînes est critique, c'est donc une utilisation souvent vue ici
membre public
Agrégat
Accesseurs
membre protégé
Fournir un accès amélioré aux classes dérivées
membre privé
Conserver les détails de mise en œuvre
Notez que les transtypages de style C permettent à dessein de convertir une classe dérivée en une classe de base protégée ou privée de manière définie et sûre et de lancer également dans l'autre sens. Cela doit être évité à tout prix, car cela peut rendre le code dépendant des détails d'implémentation - mais si nécessaire, vous pouvez utiliser cette technique.
la source
Ces trois mots clés sont également utilisés dans un contexte complètement différent pour spécifier le modèle d'héritage de visibilité .
Ce tableau regroupe toutes les combinaisons possibles de la déclaration de composant et du modèle d'héritage présentant l'accès résultant aux composants lorsque la sous-classe est complètement définie.
Le tableau ci-dessus est interprété de la manière suivante (jetez un œil à la première ligne):
Un exemple:
L'accès résultant pour les variables
p
,q
,r
en classe sous - sous est pas .L'accès résultant pour les variables
y
,z
dans la classe Sub est protégé et pour la variablex
est aucun .Permet maintenant de définir une sous-classe:
La classe définie nommée Sub qui est une sous-classe de classe nommée
Super
ou cetteSub
classe est dérivée de laSuper
classe. LaSub
classe n'introduit ni nouvelles variables ni nouvelles fonctions. Cela signifie-t-il qu'un objet de laSub
classe hérite de tous les traits après que laSuper
classe soit en fait une copie desSuper
objets d'une classe?Non . Ce n'est pas le cas.
Si nous compilons le code suivant, nous n'obtiendrons que des erreurs de compilation disant que
put
et lesget
méthodes sont inaccessibles. Pourquoi?Lorsque nous omettons le spécificateur de visibilité, le compilateur suppose que nous allons appliquer l' héritage dit privé . Cela signifie que tous les publics les composants se transforment en privé l' accès, les composants superclasse privés ne seront pas accessibles à tous. Cela signifie par conséquent que vous n'êtes pas autorisé à utiliser ce dernier à l'intérieur de la sous-classe.
Nous devons informer le compilateur que nous voulons conserver la politique d'accès utilisée précédemment.
Les objets de la
Sub
classe peuvent faire «presque» les mêmes choses que leurs frères et sœurs plus âgés créés à partir de laSuper
classe. "Presque" car le fait d'être une sous-classe signifie également que la classe a perdu l'accès aux composants privés de la superclasse . Nous ne pouvons pas écrire une fonction membre de laSub
classe qui serait capable de manipuler directement la variable de stockage.Il s'agit d'une restriction très grave. Y a-t-il une solution de contournement?
Oui .
Le troisième niveau d'accès est appelé protégé . Le mot-clé protected signifie que le composant marqué avec lui se comporte comme un public lorsqu'il est utilisé par l'une des sous-classes et ressemble à un privé pour le reste du monde . - Cela n'est vrai que pour les classes héritées publiquement (comme la classe Super dans notre exemple) -
Comme vous le voyez dans l'exemple de code, nous avons une nouvelle fonctionnalité pour la
Sub
classe et cela fait une chose importante: il accède à la variable de stockage de la classe Super .Ce ne serait pas possible si la variable était déclarée privée. Dans la portée de la fonction principale, la variable reste de toute façon cachée, donc si vous écrivez quelque chose comme:
Le compilateur vous informera qu'il s'agit d'un
error: 'int Super::storage' is protected
.Enfin, le dernier programme produira la sortie suivante:
la source
Cela concerne la façon dont les membres publics de la classe de base sont exposés à partir de la classe dérivée.
Comme litb le fait remarquer, l'héritage public est un héritage traditionnel que vous verrez dans la plupart des langages de programmation. C'est-à-dire qu'elle modélise une relation "IS-A". L'héritage privé, quelque chose d'AFAIK propre au C ++, est une relation "MISE EN ŒUVRE EN TERMES DE". Autrement dit, vous souhaitez utiliser l'interface publique dans la classe dérivée, mais vous ne voulez pas que l'utilisateur de la classe dérivée ait accès à cette interface. Beaucoup soutiennent que dans ce cas, vous devez agréger la classe de base, c'est-à-dire au lieu d'avoir la classe de base en tant que base privée, faire un membre de dérivé afin de réutiliser la fonctionnalité de la classe de base.
la source
Type d'héritage : objet hérité comme :
la source
1) Héritage public :
une. Les membres privés de la classe Base ne sont pas accessibles dans la classe Derived.
b. Les membres protégés de la classe Base restent protégés dans la classe Derived.
c. Les membres publics de la classe Base restent publics dans la classe Derived.
Ainsi, d'autres classes peuvent utiliser des membres publics de la classe Base via l'objet de classe Derived.
2) Héritage protégé :
une. Les membres privés de la classe Base ne sont pas accessibles dans la classe Derived.
b. Les membres protégés de la classe Base restent protégés dans la classe Derived.
c. Les membres publics de la classe Base deviennent également des membres protégés de la classe Derived.
Ainsi, les autres classes ne peuvent pas utiliser les membres publics de la classe Base via l'objet de classe Derived; mais ils sont disponibles pour la sous-classe de Derived.
3) Héritage privé :
une. Les membres privés de la classe Base ne sont pas accessibles dans la classe Derived.
b. Les membres protégés et publics de la classe Base deviennent des membres privés de la classe Derived.
Ainsi, aucun membre de la classe Base n'est accessible aux autres classes via l'objet de classe Derived car ils sont privés dans la classe Derived. Ainsi, même la sous-classe de la classe Derived ne peut pas y accéder.
la source
L'héritage public modélise une relation IS-A. Avec
tout
D
est unB
.L'héritage privé modélise une relation IS-IMPLEMENTED-USING (ou tout autre nom). Avec
a
D
n'est pas aB
, mais chaqueD
utilise sonB
dans sa mise en œuvre. L'héritage privé peut toujours être éliminé en utilisant le confinement à la place:Cela
D
aussi peut être implémenté en utilisantB
, dans ce cas en utilisant sonb_
. Le confinement est un couplage moins étroit entre les types que l'héritage, donc en général il devrait être préféré. Parfois, l'utilisation de confinement au lieu de l'héritage privé n'est pas aussi pratique que l'héritage privé. C'est souvent une excuse boiteuse pour être paresseux.Je ne pense pas que quiconque sache quels
protected
modèles d'héritage. Au moins, je n'ai pas encore vu d'explication convaincante.la source
D
dérive en privéD
, il peut remplacer les fonctions virtuelles deB
. (Si, par exemple,B
est une interface d'observateur, alorsD
pourrait l'implémenter et passerthis
à des fonctions nécessitant auch une interface, sans que tout le monde puisse l'utiliserD
en tant qu'observateur.) En outre,D
pourrait sélectivement rendre les membres deB
disponibles dans son interface en faisantusing B::member
. Les deux sont syntaxiquement peu pratiques à implémenter quandB
est membre.protected
héritage que j'ai trouvé utile avec unevirtual
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 publiquement d'une autre classe, tout le monde sait que vous héritez et vous pouvez être utilisé de manière polymorphe par n'importe qui via un pointeur de classe de base.
Si vous héritez de manière protégée, seules vos classes enfants pourront vous utiliser de manière polymorphe.
Si vous héritez en privé, vous seul pourrez exécuter les méthodes de la classe parent.
Ce qui symbolise fondamentalement les connaissances que les autres classes ont sur votre relation avec votre classe parent
la source
Les membres de données protégés sont accessibles à toutes les classes qui héritent de votre classe. Les membres de données privées, cependant, ne le peuvent pas. Disons que nous avons les éléments suivants:
De l'intérieur de votre extension à cette classe, le référencement
this.myPrivateMember
ne fonctionnera pas. Cependant,this.myProtectedMember
sera. La valeur est toujours encapsulée, donc si nous avons une instanciation de cette classe appeléemyObj
,myObj.myProtectedMember
cela ne fonctionnera pas, donc sa fonction est similaire à celle d'un membre de données privées.la source
Sur la base de cet exemple pour java ... je pense qu'une petite table vaut mille mots :)
la source
Sommaire:
Lors de l'héritage, vous pouvez (dans certaines langues) changer le type de protection d'un membre de données dans une certaine direction, par exemple de protégé à public.
la source
Privé:
Les membres privés d'une classe de base ne sont accessibles qu'aux membres de cette classe de base.
Publique:
Les membres publics d'une classe de base sont accessibles aux membres de cette classe de base, aux membres de sa classe dérivée ainsi qu'aux membres qui sont en dehors de la classe de base et de la classe dérivée.
Protégé:
Les membres protégés d'une classe de base sont accessibles aux membres de la classe de base ainsi qu'aux membres de sa classe dérivée.
En bref:
privé : base
protégé : base + dérivé
public : base + dérivé + tout autre membre
la source
J'ai trouvé une réponse facile et j'ai donc pensé à la poster pour ma future référence aussi.
Son des liens http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/
la source
Il s'agit essentiellement de la protection d'accès du public et des membres protégés de la classe de base dans la classe dérivée. Avec l'héritage public, la classe dérivée peut voir les membres publics et protégés de la base. Avec l'héritage privé, ce n'est pas possible. Avec protected, la classe dérivée et toutes les classes dérivées qui peuvent les voir.
la source