J'ai cherché dans SO et je n'ai pas trouvé de bonne description concernant la différence entre public
, private
et protected
L'héritage en C++. Toutes les questions supposaient un cas spécifique. Quelle est la différence ?
Réponses
Trop de publicités?class A
{
public:
int x;
protected:
int y;
private:
int z;
};
class B : public A
{
// x is public
// y is protected
// z is not accessible from B
};
class C : protected A
{
// x is protected
// y is protected
// z is not accessible from C
};
class D : private A
{
// x is private
// y is private
// z is not accessible from D
};
NOTE IMPORTANTE : Les classes B, C et D contiennent toutes les variables x, y et z. C'est juste une question d'accès.
Sur l'utilisation de l'héritage protégé et privé, vous pouvez lire ici .
Pour répondre à cette question, j'aimerais d'abord décrire les accesseurs des membres avec mes propres mots. Si vous le savez déjà, passez directement à la rubrique "suivant :".
Il existe trois accesseurs à ma connaissance : public
, protected
et private
.
Laissez :
class Base {
public:
int publicMember;
private:
int privateMember;
protected:
int protectedMember;
};
- Tout ce qui est conscient de
Base
est également conscient queBase
contientpublicMember
. - Seuls les enfants (et leurs enfants) sont conscients que
Base
contientprotectedMember
. - Personne d'autre que
Base
est conscient deprivateMember
.
Par "est conscient de", j'entends "reconnaît l'existence de, et donc est capable d'accéder à".
suivant :
Il en va de même pour l'héritage public, privé et protégé. Considérons une classe Base
et une classe Child
qui hérite de Base
.
- Si l'héritage est
public
tout ce qui est conscient deBase
etChild
est également conscient queChild
hérite de Base. - Si l'héritage est
protected
seulementChild
et ses enfants, sont conscients qu'ils héritent deBase
. - Si l'héritage est
private
, personne d'autre queChild
est conscient de l'héritage.
En limitant la visibilité de l'héritage, le code ne pourra pas voir qu'une classe hérite d'une autre classe : Les conversions implicites de la dérivée vers la base ne fonctionneront pas, et static_cast
de la base à la dérivée ne fonctionnera 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é.
public héritage
-
L'héritage IS-A. Un bouton est une fenêtre, et partout où une fenêtre est nécessaire, un bouton peut être passé aussi.
class button : public window { };
protégé héritage
-
Protégé mis en œuvre en termes de. Rarement utile. Utilisé en
boost::compressed_pair
pour dériver à partir de classes vides et économiser de la mémoire en utilisant l'optimisation des classes de base vides (l'exemple ci-dessous n'utilise pas de template pour rester dans le sujet) :struct empty_pair_impl : protected empty_class_1 { non_empty_class_2 second; }; struct pair : private empty_pair_impl { non_empty_class_2 &second() { return this->second; } empty_class_1 &first() { return *this; // notice we return *this! } };
privé héritage
-
Mis en œuvre en termes de. L'utilisation de la classe de base sert uniquement à mettre en œuvre la classe dérivée. Utile avec les traits et si la taille importe (les traits vides qui ne contiennent que des fonctions utiliseront l'optimisation de la classe de base vide). Souvent confinement est la meilleure solution, cependant. La taille des chaînes de caractères est critique, c'est pourquoi on l'utilise souvent ici.
template<typename StorageModel> struct string : private StorageModel { public: void realloc() { // uses inherited function StorageModel::realloc(); } };
public membre
-
Agrégat
class pair { public: First first; Second second; };
-
Accesseurs
class window { public: int getWidth() const; };
protégé membre
-
Fournir un accès amélioré pour les classes dérivées
class stack { protected: vector<element> c; }; class window { protected: void registerClass(window_descriptor w); };
privé membre
-
Conserver les détails de la mise en œuvre
class window { private: int width; };
Notez que les castings de style C permettent délibérément de faire un casting d'une classe dérivée vers une classe de base protégée ou privée d'une manière définie et sûre et de faire un casting dans l'autre sens également. Cela devrait ê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.
Il s'agit de la façon dont les membres publics de la classe de base sont exposés dans la classe dérivée.
- public -> les membres publics de la classe de base seront publics (généralement par défaut).
- protected -> les membres publics de la classe de base seront protégés.
- private -> les membres publics de la classe de base seront privés.
Comme le souligne litb, l'héritage public est l'héritage traditionnel que l'on retrouve dans la plupart des langages de programmation. C'est-à-dire qu'il modélise une relation "IS-A". L'héritage privé, quelque chose d'AFAIK particulier au C++, est une relation "MISE EN ŒUVRE EN TERMES DE". C'est-à-dire que vous voulez utiliser l'interface publique dans la classe dérivée, mais ne veulent pas que l'utilisateur de la classe dérivée ait accès à cette interface. Beaucoup soutiennent que dans ce cas, il faut agréger la classe de base, c'est-à-dire qu'au lieu d'avoir la classe de base comme base privée, il faut en faire un membre de la classe dérivée afin de réutiliser la fonctionnalité de la classe de base.
- Réponses précédentes
- Plus de réponses