J'ai appris que je ne peux jamais accéder à une variable privée, uniquement avec une fonction get dans la classe. Mais alors pourquoi puis-je y accéder dans le constructeur de copie?
Exemple:
Field::Field(const Field& f)
{
pFirst = new T[f.capacity()];
pLast = pFirst + (f.pLast - f.pFirst);
pEnd = pFirst + (f.pEnd - f.pFirst);
std::copy(f.pFirst, f.pLast, pFirst);
}
Ma déclaration:
private:
T *pFirst,*pLast,*pEnd;
À mon humble avis, les réponses existantes expliquent mal le "pourquoi" de cela - en se concentrant trop sur la réitération de ce comportement valide. "les modificateurs d'accès fonctionnent au niveau de la classe et non au niveau de l'objet." - Oui mais pourquoi?
Le concept global ici est que c'est le ou les programmeurs qui conçoivent, écrivent et maintiennent une classe qui sont censés comprendre l'encapsulation OO souhaitée et habilitée à coordonner son implémentation. Donc, si vous écrivez class X
, vous encodez non seulement comment un objet X x
individuel peut être utilisé par du code avec accès, mais aussi comment:
X
distincts coopérer pour fournir les comportements voulus tout en respectant les post-conditions et les invariants de votre conception.Ce n'est pas seulement le constructeur de copie non plus - un grand nombre d'opérations peuvent impliquer deux instances ou plus de votre classe: si vous comparez, ajoutez/multipliez/divisez, copiez-construisez, clonez, attribuez etc., alors c'est souvent le cas que vous soit doit simplement avoir accès à des données privées et/ou protégées dans l'autre objet, soit vouloir qu'il permette une implémentation de fonction plus simple, plus rapide ou généralement meilleure.
Plus précisément, ces opérations peuvent vouloir profiter d'un accès privilégié pour faire des choses comme:
shared_ptr
pour référencer des données, etc.auto_ptr<>
"Déplace" la propriété vers l'objet en constructionunordered_map
mais n'expose publiquement que les itérateurs begin()
et end()
- avec un accès direct à size()
vous pourriez reserve
capacité pour copie plus rapide; pire encore s'ils n'exposent que at()
et insert()
et sinon throw
....Les modificateurs d'accès fonctionnent sur niveau classe, et non sur niveau objet.
Autrement dit, deux objets de la même classe peuvent accéder l'un à l'autre aux données privées.
Principalement en raison de l'efficacité. Ce serait un temps d'exécution non négligeable pour vérifier si this == other
chaque fois que vous accédez à other.x
ce que vous auriez à faire si les modificateurs d'accès fonctionnaient au niveau de l'objet.
C'est aussi un peu sémantiquement logique si vous y pensez en termes de portée: "Quelle partie du code dois-je garder à l'esprit lors de la modification d'une variable privée?" - Vous devez garder à l'esprit le code de toute la classe, et c'est orthogonal aux objets qui existent en runtime.
Et c'est incroyablement pratique lors de l'écriture de constructeurs de copie et d'opérateurs d'affectation.
Vous pouvez accéder aux membres privés d'une classe depuis la classe, même ceux d'une autre instance.
Pour comprendre la réponse, je voudrais vous rappeler quelques notions.
this
le pointeur est passé à chaque fonction lors de son appel.Maintenant, c'est à cause du pointeur this
, la fonction est capable de localiser les variables de cette instance particulière. peu importe si elle est privée ou publique. il est accessible à l'intérieur de cette fonction. Maintenant, si nous passons un pointeur vers un autre objet de la même classe. en utilisant ce deuxième pointeur, nous pourrons accéder aux membres privés.
J'espère que ça répond à ta question.
Le constructeur de copie est une fonction membre de la classe et, en tant que tel, a accès aux membres de données de la classe, même ceux déclarés comme "privés".