À 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 un X x
objet individuel peut être utilisé par le code avec accès à celui-ci, mais aussi comment:
- les classes dérivées sont capables d'interagir avec lui (via des fonctions virtuelles optionnellement pures et / ou un accès protégé), et
- des
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:
- (les constructeurs de copie) utilisent un membre privé de l'objet "rhs" (côté droit) dans une liste d'initialisation, de sorte qu'une variable membre est elle-même construite par copie au lieu d'être construite par défaut (même si elle est légale) puis assignée aussi (encore une fois, si légal)
- partager des ressources - descripteurs de fichiers, segments de mémoire partagée,
shared_ptr
s pour référencer des données, etc.
- s'approprier des choses, par exemple
auto_ptr<>
"déplacer" la propriété vers l'objet en construction
- copier le "cache" privé, l'étalonnage ou les membres d'état nécessaires pour construire le nouvel objet dans un état utilisable de manière optimale sans avoir à les régénérer à partir de zéro
- copie / accès aux informations de diagnostic / trace conservées dans l'objet en cours de copie qui ne sont pas autrement accessibles via les API publiques, mais peuvent être utilisées par un objet d'exception ou une journalisation ultérieure (par exemple, quelque chose sur le moment / les circonstances où l'instance "d'origine" non construite par copie a été construit)
- effectuer une copie plus efficace de certaines données: par exemple, les objets peuvent avoir, par exemple, un
unordered_map
membre mais uniquement exposer publiquement begin()
et des end()
itérateurs - avec un accès direct à size()
vous pourrait permettre reserve
une copie plus rapide; pire encore s'ils ne font qu'exposer at()
et insert()
et autrement throw
....
- recopier les références aux objets parents / coordination / gestion qui pourraient être inconnus ou en écriture seule pour le code client