2008-10-22 15 views
200

Quelqu'un peut-il m'éclairer sur la différence entre les membres privés et protégés dans les classes? Je comprends des conventions de meilleure pratique que les variables et les fonctions qui ne sont pas appelées en dehors de la classe doivent être rendues privées - mais en regardant mon projet MFC, MFC semble privilégier protégé.Membres privés et protégés: C++

Quelle est la différence et que devrais-je utiliser?

Répondre

287

Les membres privés ne sont accessibles que dans la classe qui les définit.

Les membres protégés sont accessibles dans la classe qui les définit et dans les classes qui héritent de cette classe. Edit: Les deux sont également accessibles par des amis de leur classe, et dans le cas de membres protégés, par des amis de leurs classes dérivées.

Édition 2: Utilisez ce qui est logique dans le contexte de votre problème. Vous devriez essayer de rendre les membres privés chaque fois que vous le pouvez pour réduire le couplage et protéger l'implémentation de la classe de base, mais si cela n'est pas possible, utilisez des membres protégés. Vérifiez C++ FAQ pour une meilleure compréhension du problème. This question about protected variables pourrait également aider.

+7

Le lien vers C++ FAQ Lite a été déplacé vers https://isocpp.org/wiki/faq/basics-of-inheritance – avner

5

Les attributs et méthodes marqués protected sont - contrairement aux codes privés - encore visibles dans les sous-classes.

Sauf si vous ne voulez pas utiliser ou fournir la possibilité de remplacer la méthode dans les sous-classes possibles, je les ferais private.

+1

Une classe dérivée peut remplacer les fonctions virtuelles privées de sa base –

+0

Ah oui, vous avez raison. Merci! – fhe

4

Les membres protégés ne sont accessibles qu'aux descendants de la classe et au code du même module. Les membres privés ne sont accessibles que par la classe dans laquelle ils sont déclarés et par le code dans le même module.

Bien sûr, les fonctions d'amis jettent ça par la fenêtre, mais bon.

4

Les membres privés sont uniquement accessibles depuis la classe, les membres protégés sont accessibles dans la classe et les classes dérivées. C'est une caractéristique de l'héritage dans les langages OO.

Vous pouvez avoir un héritage privé, protégé et public en C++, qui déterminera quelles classes dérivées peuvent accéder à la hiérarchie d'héritage. C# par exemple a seulement l'héritage public.

44

Les membres protégés sont accessibles depuis les classes dérivées. Les privés ne peuvent pas.

class Base { 

private: 
    int MyPrivateInt; 
protected: 
    int MyProtectedInt; 
public: 
    int MyPublicInt; 
} 

class Derived : Base 
{ 
public: 
    int foo1() { return MyPrivateInt;} // Won't compile! 
    int foo2() { return MyProtectedInt;} // OK 
    int foo3() { return MyPublicInt;} // OK 
}; 

class Unrelated 
{ 
private: 
    Base B; 
public: 
    int foo1() { return B.MyPrivateInt;} // Won't compile! 
    int foo2() { return B.MyProtectedInt;} // Won't compile 
    int foo3() { return B.MyPublicInt;} // OK 
}; 

En termes de "meilleure pratique", cela dépend. S'il y a même une faible possibilité que quelqu'un veuille dériver une nouvelle classe de votre existante et avoir besoin d'accéder aux membres internes, faites-les Protégé, pas Privé. Si elles sont privées, votre classe peut devenir difficile à hériter facilement.

+3

Je ne suis pas d'accord: s'il y a une faible possibilité que _no_ subclass en ait besoin, rendez-le privé. À moins que vous ne souhaitiez que votre classe soit sous-classée, utilisez le modèle de méthode de modèle. – xtofl

21

La raison pour laquelle MFC favorise la protection, c'est parce que c'est un cadre. Vous voulez probablement sous-classer les classes MFC et dans ce cas, une interface protégée est nécessaire pour accéder aux méthodes qui ne sont pas visibles par l'utilisation générale de la classe.

105

Publique Les membres d'une classe A sont accessibles à tous.

Protégé Les membres d'une classe A ne sont pas accessibles en dehors du code de A, mais sont accessibles depuis le code de n'importe quelle classe dérivée de A.

privés membres d'une classe A ne sont pas accessibles en dehors du code A ou du code de toute classe dérivée de A.

Ainsi, à la fin, le choix entre protégé ou privé répondant aux questions suivantes questions: Combien de confiance êtes-vous prêt à mettre dans le programmeur de la classe dérivée?

Par défaut, supposons que la classe dérivée est de ne pas faire confiance, et faire vos membres privés. Si vous avez une très bonne raison de donner un accès gratuit aux internes de la classe mère à ses classes dérivées, alors vous pouvez les protéger.

+0

La classe dérivée doit être un type de votre classe et les données protégées de la classe de base font partie des données de la classe dérivée. L'auteur de la classe dérivée doit gérer correctement ces données ou il s'agit d'un bogue. Les données privées dans une classe de base sont cependant quelque chose que l'auteur de la classe dérivée ne contrôle pas. – CashCow

+0

@CashCow 'les données protégées de la classe de base font partie des données de la classe dérivée. Ne vaut-il pas mieux, alors, que l'auteur de la classe dérivée déclare ces données dans sa classe, au lieu de la mienne? ... :-) ... 'L'auteur de la classe dérivée devrait gérer correctement ces données ou c'est un bogue. »Dans le modèle NVI, le but est de rendre tout ce qui est privé, y compris les méthodes, pour limiter les dommages que le rédacteur de classe dérivé pourrait faire à la hiérarchie. Les méthodes protégées sont déjà un problème potentiel. Je ne suis pas convaincu d'aggraver cela en utilisant l'état protégé est la bonne approche. – paercebal

+0

Cela pourrait être, ce qui vous obligerait à avoir des "getters" virtuels dans la classe de base pour y accéder. Et tandis que vous pouvez avoir des classes intermédiaires pour faire les différentes façons dont le modèle de données peut être implémenté, il n'est pas toujours pratique de le faire. Par exemple, un "pattern", commun dans les langages qui n'ont pas de modificateur "const" bien que cela ne soit pas nécessaire la plupart du temps en C++, doit avoir une classe de base en lecture seule et des classes dérivées inscriptibles. En C++ cela peut aussi être sympa simplement parce que vous voulez plus d'un moyen possible de charger (initialiser) les données. – CashCow

8

Tout dépend de ce que vous voulez faire et de ce que vous voulez que les classes dérivées puissent voir.

class A 
{ 
private: 
    int _privInt = 0; 
    int privFunc(){return 0;} 
    virtual int privVirtFunc(){return 0;} 
protected: 
    int _protInt = 0; 
    int protFunc(){return 0;} 
public: 
    int _publInt = 0; 
    int publFunc() 
    { 
     return privVirtFunc(); 
    } 
}; 

class B : public A 
{ 
private: 
    virtual int privVirtFunc(){return 1;} 
public: 
    void func() 
    { 
     _privInt = 1; // wont work 
     _protInt = 1; // will work 
     _publInt = 1; // will work 
     privFunc(); // wont work 
     privVirtFunc(); // wont work 
     protFunc(); // will work 
     publFunc(); // will return 1 since it's overridden in this class 
    } 
} 
4

Bien sûr, jetez un oeil à la question Protected Member Variables. Il est recommandé d'utiliser private par défaut (tout comme C++ class ses) pour réduire le couplage. Les variables membres protégées sont le plus souvent une mauvaise idée, les fonctions membres protégées peuvent être utilisées par exemple. le modèle de méthode de modèle.

+0

Drôle, j'ai édité cela à mon poste avant que j'ai vu le vôtre. Upvoted parce que les oiseaux d'une plume trébuchent sur le même lien :) –

3

puisque aucune fonction de membre public n'est nécessaire pour récupérer et mettre à jour les membres protégés dans la classe dérivée, ceci augmente l'efficacité du code et réduit la quantité de code que nous devons écrire. Cependant programmeur de classe dérivée est censé être conscient de ce qu'il fait.

2

Un membre privé ne peut être accédé que dans la même classe où il a déclaré où l'on peut accéder en tant que membre protégé en classe où il est déclaré avec les classes dont il est hérité.

0

A protégé membre non statique de classe de base est accessible par les membres et amis de toutes les classes dérivées de cette classe de base en utilisant une des méthodes suivantes:

  • Un pointeur sur une classe dérivée directement ou indirectement
  • une référence à un dérivé directement ou indirectement classe
  • un objet d'un dérivé directement ou indirectement classe
+0

Quelle valeur votre réponse ajoute-t-elle aux autres réponses? –

2

privé: Il est un spécificateur d'accès. Par défaut, les variables d'instance (membre) ou les méthodes d'une classe dans C++/java sont privées. Pendant l'héritage, le code et les données sont toujours hérités mais ne sont pas accessibles en dehors de la classe. Nous pouvons déclarer nos membres de données comme privés afin que personne ne puisse apporter des changements directs à nos variables membres et nous pouvons fournir des getters et setters publics afin de changer nos membres privés. Et ce concept est toujours appliqué dans la règle métier.

Protégé: C'est également un spécificateur d'accès. En C++, les membres protégés sont accessibles dans la classe et dans la classe héritée, mais pas en dehors de la classe. En Java, les membres protégés sont accessibles dans la classe, dans la classe héritée ainsi que dans toutes les classes du même paquet.

0

Les modificateurs d'accès privés et protégés sont un seul et même seulement que les membres protégés de la classe de base peuvent être accédés en dehors de la portée de la classe de base dans la classe enfant (dérivé). Il s'applique également à l'héritage. Mais avec le modificateur privé les membres de la classe de base ne sont accessibles dans le champ ou le code de la classe de base et de ses fonctions d'ami que « » « »

+2

Quelle valeur votre réponse ajoute-t-elle aux autres réponses? –

3

privé = accessible par le ravitailleur (classe de base) seulement (c.-à-que mon parent peut aller dans la chambre de mes parents)

protégé = accessible par navire ravitailleur (classe de base), et ses filles (c.-à-que mes parents peut aller dans la chambre de mes parents, mais a donné le fils/permission de fille de marcher dans la chambre des parents)

publique = accessible par navire ravitailleur (classe de base), la fille, et tout le monde (c.-à-que mon parent peut aller dans ma chambre des parents, mais il est une fête - mi casa su casa)

Questions connexes