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;
c++
private
access-specifier
roi démon
la source
la source
const&
getter public ou par valeur pour chacun? Ensuite, ils ne sont que 'write-private', & pour les valeurs gaspillent des ressources et échouent pour les membres non copiables.) Je suis déconcerté par un tel succès d'une question aussi vide, posant des questions sur la construction de copie tout en ignorant totalement ce que cela signifie, et aucune réponse n'utilise une logique de base pour la démystifier. Ils expliquent des technicités sèches, mais il y a une réponse beaucoup plus simple à une question aussi clignotanteRéponses:
À mon humble avis, les réponses existantes font un mauvais travail expliquant 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 ce sont les programmeurs qui conçoivent, écrivent et maintiennent une classe qui doivent comprendre l'encapsulation OO souhaitée et être habilités à coordonner sa mise en œuvre. Donc, si vous écrivez
class X
, vous encodez non seulement comment unX x
objet individuel peut être utilisé par le code avec accès à celui-ci, mais aussi comment:X
objets distincts coopèrent pour fournir les comportements prévus 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 ou plusieurs instances de votre classe: si vous comparez, ajoutez / multipliez / divisez, copiez-construisez, clonez, affectez, 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 souhaiter profiter d'un accès privilégié pour effectuer des actions telles que:
shared_ptr
s pour référencer des données, etc.auto_ptr<>
"déplacer" la propriété vers l'objet en constructionunordered_map
membre mais uniquement exposer publiquementbegin()
et desend()
itérateurs - avec un accès direct àsize()
vous pourrait permettrereserve
une copie plus rapide; pire encore s'ils ne font qu'exposerat()
etinsert()
et autrementthrow
....la source
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.this == other
chaque fois que vous accédezother.x
" - manque le point - siother.x
c'était seulement accepté au moment de l'exécution quand équivalent àthis.x
, il n'y aurait pas beaucoup d'écriture de pointeurother.x
en premier lieu; le compilateur pourrait aussi bien vous forcer à écrireif (this == other) ...this.x...
pour tout ce que vous allez faire. Votre conception de la «commodité (encore plus si les variables privées étaient publiques)» passe également à côté de l'essentiel - la façon dont la norme est définie est suffisamment restrictive pour permettre une encapsulation correcte , mais pas inutilement gênante.Les modificateurs d'accès fonctionnent au niveau de la classe et non au niveau de l'objet .
Autrement dit, deux objets de la même classe peuvent accéder les uns aux autres aux données privées.
Pourquoi:
Principalement en raison de l'efficacité. Ce serait une surcharge d'exécution non négligeable de 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 réfléchissez en termes de portée: "Quelle est la taille 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 à quels objets existent au moment de l'exécution.
Et c'est incroyablement pratique lors de l'écriture de constructeurs de copie et d'opérateurs d'affectation.
la source
Vous pouvez accéder aux membres privés d'une classe à partir de la classe, même à ceux d'une autre instance.
la source
Pour comprendre la réponse, je voudrais vous rappeler quelques notions.
this
Le pointeur est passé à chaque fonction lorsqu'il est appelé.Maintenant, c'est grâce au
this
pointeur, que la fonction est capable de localiser les variables de cette instance particulière. peu importe si c'est privé ou public. il est accessible dans 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.
la source
Le constructeur de copie est une fonction membre de la classe et, en tant que tel, a accès aux données membres de la classe, même celles déclarées comme «privées».
la source