91 votes

Pourquoi les objets de la même classe ont-ils accès aux données privées les uns des autres?

Pourquoi les objets de la même classe ont-ils accès aux données privées les uns des autres?

 class TrivialClass {
public: 
  TrivialClass(const std::string& data) :
    mData(data) {};

  const std::string& getData(const TrivialClass& rhs) const {
    return rhs.mData;
  };

private:
  std::string mData;
};

int main() {
  TrivialClass a("fish");
  TrivialClass b("heads");

  std::cout << "b via a = " << a.getData(b) << std::endl;
  return 0;
}
 

Ce code fonctionne. Il est parfaitement possible que l’objet a accède aux données privées de l’objet b et les renvoie. Pourquoi devrait-il en être ainsi? Je penserais que les données privées sont privées. (J'ai commencé par essayer de comprendre les constructeurs de copie dans l'idiome pimpl, mais j'ai ensuite découvert que je n'avais même pas compris cette situation simple.)

74voto

AndreyT Points 139512

Parce que c'est la façon dont il fonctionne en C++. En C++ de contrôle d'accès fonctionne sur par classe de base, et non pas sur chaque objet.

Contrôle d'accès en C++ est mis en œuvre comme un statique, au moment de la compilation de la fonctionnalité. Je pense qu'il est plutôt évident que ce n'est pas vraiment possible de mettre en œuvre significative, par objet de contrôle d'accès au moment de la compilation. Seulement par la classe de contrôle peuvent être mises en œuvre de cette façon.

Quelques conseils de par objet de contrôle sont présents dans l'accès protégé cahier des charges, qui est pourquoi il a même son propre chapitre dans la norme (11.5). Mais encore par les caractéristiques des objets qui y sont décrits sont plutôt rudimentaires. Encore une fois, le contrôle d'accès en C++ est censé travailler sur la fonction de la classe.

28voto

vsekhar Points 1065

"Privé" n'est pas vraiment un mécanisme de contrôle d'accès au sens de "J'ai fait mes photos sur facebook privé pour que vous ne puissiez pas les voir".

En C ++, "privé" indique simplement qu'il s'agit de parties d'une classe que vous (le codeur de la classe) pouvez modifier dans les versions futures, etc., et que vous ne voulez pas que les autres codeurs utilisant votre classe s'appuient sur leur existence ou leurs fonctionnalités. .

Si vous souhaitez un véritable contrôle d'accès, vous devez implémenter de véritables techniques de sécurité des données.

11voto

André Caron Points 19543

C'est un peu de l'arbitraire d'un langage de conception de décision. En Ruby, par exemple, private signifie vraiment privé, comme dans "seule l'instance peut avoir accès à ses propres données privées des membres". Cependant, c'est un peu restrictif.

Comme signalé dans les commentaires, copie des constructeurs et des opérateurs d'affectation sont des lieux communs où vous accédez à une autre instance des données privées des membres directement. Il y a des raisons moins évidentes pourquoi.

Considérons le cas suivant. Vous êtes à la mise en œuvre d'un OO liste liée. La liste liée a un nœud imbriqué classe pour la gestion des pointeurs. Vous pourriez mettre en œuvre cette classe de nœud tel qu'il gère les pointeurs lui-même (plutôt que d'avoir des pointeurs public et géré par la liste). Dans un tel cas, vous auriez les objets de nœud qui veulent modifier d'autres objets de nœud' pointeurs à d'autres endroits que le constructeur de copie et l'opérateur d'affectation.

4voto

Adam Maras Points 14517

L'astuce consiste à rappeler que les données sont private pour la classe , pas l' instance de la classe. Toute méthode de votre classe peut accéder aux données privées de toute instance de cette classe; il n'y a pas moyen de garder les données privées dans une instance sauf si vous interdisez les méthodes qui accèdent explicitement aux données privées membres d'autres instances.

-7voto

YeenFei Points 2100

Les données privées restent privées jusqu'à ce que quelqu'un qui y a accès les révèle à d'autres.

Ce concept s'applique également à d'autres situations, telles que:

 class cMyClass
{
public:
   // ...
   // omitted for clarity
   // ...

   void Withdraw(int iAmount)
   {
      iTheSecretVault -= iAmount;
   }

private:
   int iTheSecretVault;
};
 

Comment peut-on retirer l'argent? :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X