Pourquoi les objets de la même classe ont-ils accès aux données privées de chacun?
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 pour l'objet a d'accéder aux données privées de l'objet b et de les renvoyer. Pourquoi devrait-il en être ainsi? Je pense 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 ne comprenais même pas cette situation simple.)
c++
private-members
Keith
la source
la source
Réponses:
Parce que c'est ainsi que cela fonctionne en C ++. En C ++, le contrôle d'accès fonctionne sur une base par classe , pas sur une base par objet.
Le contrôle d'accès en C ++ est implémenté en tant que fonctionnalité statique au moment de la compilation. Je pense qu'il est assez évident qu'il n'est pas vraiment possible d'implémenter un contrôle d'accès par objet significatif au moment de la compilation. Seul le contrôle par classe peut être implémenté de cette façon.
Certains indices de contrôle par objet sont présents dans la spécification d' accès protégé , c'est pourquoi elle a même son propre chapitre dédié dans la norme (11.5). Mais toutes les fonctionnalités par objet décrites ici sont plutôt rudimentaires. Encore une fois, le contrôle d'accès en C ++ est censé fonctionner par classe.
la source
void X::f(X&x)
, le compilateur est facilement capable de distinguerthis->a
etx.a
. Il n'est pas (toujours) possible pour le compilateur de savoir cela*this
etx
sont en fait le même objet six.f(x)
est invoqué, mais je pourrais très bien voir un concepteur de langage trouver cela OK.this
et&x
sont identiques. Pour aggraver les choses, cela finit par être un problème même avecX::f(Y& y)
, car notre objet concret pourrait être d'un typeZ
qui hérite des deuxX
etY
. Bref, c'est un vrai bordel, pas performant, difficile à faire travailler raisonnablement avec MI.X::f(X& x)
, s'il y a des accès àx.a
, il ne compilerait pas. Rien d'autre ne change, aucune vérification ne doit être insérée, les performances des programmes encore valides ne sont donc pas affectées. Et cela n'est pas suggéré comme un changement radical du C ++ existant, mais comme quelque chose que les concepteurs auraient pu faire lors de l'introductionprivate
initiale.«Privé» n'est pas vraiment un mécanisme de contrôle d'accès dans le sens de «J'ai rendu mes photos privées sur Facebook pour que vous ne puissiez pas les voir».
En C ++, «privé» dit simplement qu'il s'agit de parties d'une classe que vous (le codeur de la classe) pourriez changer dans les versions futures, etc., et 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 mettre en œuvre de véritables techniques de sécurité des données.
la source
C'est une bonne question et je l'ai rencontrée récemment. J'ai eu quelques discussions avec mes collègues et voici le résumé de notre discussion: C'est voulu. Cela ne signifie pas que cette conception est totalement raisonnable pour tous les cas, mais il doit y avoir des considérations pour lesquelles chaque classe privée est choisie. Les raisons possibles auxquelles nous pourrions penser incluent:
Tout d'abord, le coût du contrôle d'accès par instance peut être très élevé. Cela a été discuté par d'autres dans ce fil. En théorie, cela peut être fait via cette vérification du pointeur. Cependant, cela ne peut pas être fait au moment de la compilation et ne peut être fait qu'au moment de l'exécution. Vous devez donc identifier le contrôle d'accès de chaque membre au moment de l'exécution, et en cas de violation, seules des exceptions seront déclenchées. Le coût est élevé.
Deuxièmement, le contrôle d'accès par classe a son propre cas d'utilisation, comme le constructeur de copie ou l'opérateur =. Il serait difficile de les implémenter si le contrôle d'accès est par instance.
De plus, le contrôle d'accès est principalement du point de vue de la programmation / du langage, pour savoir comment modulariser / contrôler l'accès au code / membre, pas aux données.
la source
C'est en quelque sorte une décision arbitraire de conception de langage. Dans Ruby , par exemple,
private
signifie vraiment privé, comme dans "seule l'instance peut accéder à ses propres données privées membres". Cependant, c'est quelque peu restrictif.Comme indiqué dans les commentaires, les constructeurs de copie et les opérateurs d'affectation sont des endroits courants où vous accédez directement aux membres de données privées d'une autre instance. Il y a des raisons moins évidentes.
Prenons le cas suivant. Vous implémentez une liste chaînée OO. La liste chaînée a une classe de nœuds imbriqués pour la gestion des pointeurs. Vous pouvez implémenter cette classe de nœuds de telle sorte qu'elle gère les pointeurs elle-même (plutôt que d'avoir les pointeurs publics et gérés par la liste). Dans un tel cas, les objets nœud voudraient modifier les pointeurs d'autres objets nœud à d'autres endroits que le constructeur et l'opérateur d'affectation typiques copient.
la source
L'astuce consiste à se rappeler que les données appartiennent
private
à la classe et non à 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 de 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.la source
En plus de toutes les réponses ci-dessus, considérez les constructeurs de copie personnalisés, les opérateurs d'affectation et toutes les autres fonctions que vous écririez pour une classe qui opèrent sur d' autres instances . Vous auriez besoin de fonctions d'accesseur pour tous ces membres de données.
la source
Les données privées restent privées jusqu'à ce que quelqu'un qui y ait accès les révèle à d'autres.
Ce concept s'applique également à d'autres situations, telles que:
Comment quelqu'un pourrait-il retirer l'argent? :)
la source