web-dev-qa-db-fra.com

Membres privés et protégés: C++

Quelqu'un peut-il m'éclairer sur la différence entre les membres private et protected dans les classes?

D'après les conventions de meilleures pratiques, les variables et les fonctions qui ne sont pas appelées en dehors de la classe doivent être rendues private - mais en regardant monMFCprojet,MFCsemble favoriser protected.

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

236
Konrad

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 aux amis de leur classe et, dans le cas des membres protégés, aux amis de leurs classes dérivées.

Edit 2: Utilisez ce qui a du sens dans le contexte de votre problème. Vous devez 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 ce n'est pas possible, utilisez des membres protégés. Vérifiez C++ FAQ pour une meilleure compréhension du problème. Cette question sur les variables protégées pourrait également aider.

326
Firas Assaad

Public Les membres d'une classe A sont accessibles à tous et à toutes.

Protected les membres d'une classe A ne sont pas accessibles en dehors du code de A, mais sont accessibles à partir du code de toute classe dérivée de A.

Private les membres d'une classe A ne sont pas accessibles en dehors du code de A, ou du code d'une classe dérivée de A.

Donc, au final, choisir entre protégé ou privé répond aux questions suivantes: Quel degré de confiance êtes-vous prêt à accorder au programmeur de la classe dérivée?

Par défaut , supposons que la classe dérivée ne doit pas être approuvée, et rend vos membres privés . Si vous avez une très bonne raison de donner libre accès aux internes de la classe mère à ses classes dérivées, vous pouvez les protéger.

119
paercebal

Les membres protégés sont accessibles à partir de 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 existe même une faible possibilité qu'une personne veuille dériver une nouvelle classe de votre classe existante et qu'elle ait besoin d'accéder aux membres internes, définissez-les comme étant protégées, et non privées. S'ils sont privés, votre classe peut devenir difficile à hériter facilement.

55
Roddy

La raison pour laquelle MFC favorise la protection est qu’il s’agit d’un cadre. Vous souhaitez probablement sous-classer les classes MFC et dans ce cas, une interface protégée est nécessaire pour accéder aux méthodes non visibles pour une utilisation générale de la classe.

21
Toon Krijthe

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
    }
}
8
Mats Fredriksson

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

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

5
fhe

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

4
xtofl

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

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

4

les membres private ne sont accessibles que depuis la classe, les membres protégés sont accessibles dans la classe et les classes dérivées. C'est une caractéristique d'héritage dans les langues OO.

Vous pouvez avoir des héritages privés, protégés et publics en C++, qui détermineront les classes dérivées pouvant accéder à la hiérarchie d'héritage. C # par exemple n'a qu'un héritage public.

4
PhilGriffin

private = accessible uniquement par le vaisseau mère (classe de base) .__ (seul mon parent peut aller dans la chambre de mon parent)

protected = accessible par le vaisseau mère (classe de base) et ses filles (c’est-à-dire que seul mes parents peuvent entrer dans la chambre de mes parents, mais a donné l’autorisation à son fils/à sa fille de pénétrer dans la chambre de ses parents)

public = accessible par vaisseau mère (classe de base), par fille et par tous les autres (Seul mon parent peut entrer dans la chambre de mes parents, mais c'est une fête à la maison - mi casa su casa)

3
Johan K. Rhodes

Comme aucune fonction de membre public n'est nécessaire pour extraire et mettre à jour les membres protégés de la classe dérivée, cela augmente l'efficacité du code et réduit la quantité de code à écrire. Cependant, le programmeur de la classe dérivée est censé être au courant de ce qu'il fait.

2
null

private est préférable pour les données de membre. Les membres des classes C++ sont private par défaut. 

public est préférable pour les fonctions membres, bien que ce soit une question d'opinion. Au moins certaines méthodes doivent être accessibles. public est accessible à tous. C'est l'option la plus flexible et la moins sûre. Tout le monde peut les utiliser et tout le monde peut en abuser.

private n'est pas accessible du tout. Personne ne peut les utiliser en dehors de la classe et personne ne peut en abuser. Pas même dans les classes dérivées.

protected est un compromis car il peut être utilisé dans des classes dérivées. Lorsque vous venez d'une classe, vous comprenez bien la classe de base et vous veillez à ne pas abuser de ces membres.

MFC est un wrapper C++ pour les API Windows, il préfère public et protected. Les classes générées par l'assistant Visual Studio ont un mélange déplaisant de membres protected, public et private. Mais il existe une certaine logique aux classes MFC elles-mêmes.

Les membres tels que SetWindowText sont public car vous devez souvent accéder à ces membres.

Des membres tels que OnLButtonDown traitent les notifications reçues par la fenêtre. Ils ne doivent pas être consultés, ils sont donc protected. Vous pouvez toujours y accéder dans la classe dérivée pour remplacer ces fonctions.

Certains membres doivent faire des threads et des boucles de messages, ils ne doivent pas être accédés ni remplacés, ils sont donc déclarés comme private

Dans les structures C++, les membres sont public par défaut. Les structures sont généralement utilisées pour les données uniquement et non pour les méthodes. Par conséquent, la déclaration public est considérée comme étant sûre.

1
Barmak Shemirani
  • Private : C'est un spécificateur d'accès. Par défaut, les variables d'instance (membre) ou les méthodes d'une classe en c ++/Java sont privées. Lors de 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 données membres comme privées afin que personne ne puisse modifier directement nos variables de membre et nous pouvons fournir des accesseurs et des passeurs publics afin de modifier nos membres privés. Et ce concept est toujours appliqué dans la règle de gestion.

  • Protected : C'est aussi un spécificateur d'accès. En C++, les membres protégés sont accessibles au sein de la classe et de la classe héritée, mais pas en dehors de la classe. En Java, les membres protégés sont accessibles au sein de la classe, à la classe héritée ainsi qu'à toutes les classes d'un même package.

1
Tutu Kumari

Un membre privé est accessible uniquement dans la même classe où il a déclaré que, en tant que membre protégé, il est accessible dans une classe où il est déclaré, ainsi que les classes dont il hérite.

1
Gayki

Les membres et amis de toutes les classes dérivées de cette classe de base peuvent accéder aux membres d'une classe de base non statique protégée en utilisant l'un des éléments suivants:

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

Private: Accessible par les fonctions membres de la classe et la fonction ami ou la classe ami . Pour la classe C++, il s'agit du spécificateur d'accès par défaut.

Protected: Accessible par les fonctions membres de la classe, la fonction ami ou la classe amie et les classes dérivées.

  • Vous pouvez conserver la variable ou la fonction membre de la classe (même les classes de caractères ou les classes internes) comme privée ou protégée selon vos besoins.
  • La plupart du temps, vous gardez membre de la classe en tant que personne privée et ajoutez des fonctions get/set à encapsuler. Cela aide à la maintenance du code.
  • Généralement, la fonction privée est utilisée lorsque vous souhaitez garder vos fonctions publiques modulaires ou éliminer le code répété au lieu d'écrire du code complet dans une seule fonction. Cela aide à la maintenance du code.

Référez-vous à ce lien pour plus de détails.

0
Darshan Rajgor