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?
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.
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.
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.
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.
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
}
}
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
.
Bien sûr, jetez un oeil à la Variables membres protégées question. Il est recommandé d'utiliser privé par défaut (comme C++ class
ses 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.
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.
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.
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)
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.
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.
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.
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.
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:
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.
Référez-vous à ce lien pour plus de détails.