Il y a plusieurs raisons pour lesquelles il est mauvais de renvoyer des références (ou des pointeurs) vers les internes d'une classe. En commençant par (ce que je considère être) la plus importante :
-
Encapsulation est violée : vous divulguez un détail d'implémentation, ce qui signifie que vous ne pouvez plus modifier les internes de votre classe comme vous le souhaitez. Si vous avez décidé de ne pas stocker first_
par exemple, mais pour le calculer à la volée, comment retourner une référence à celui-ci ? Vous ne pouvez pas, donc vous êtes coincé.
-
Invariant ne sont plus viables (dans le cas d'une référence non-const) : n'importe qui peut accéder et modifier à volonté l'attribut auquel il est fait référence, vous ne pouvez donc pas "surveiller" ses changements. Cela signifie que vous ne pouvez pas maintenir un invariant dont cet attribut fait partie. Essentiellement, votre classe se transforme en un blob.
-
À vie Des problèmes surgissent : il est facile de conserver une référence ou un pointeur vers l'attribut après que l'objet original auquel ils appartiennent a cessé d'exister. Il s'agit bien entendu d'un comportement non défini. La plupart des compilateurs essaieront de mettre en garde contre la conservation de références à des objets sur la pile, par exemple, mais je ne connais aucun compilateur qui ait réussi à produire de tels avertissements pour les références renvoyées par des fonctions ou des méthodes : vous devez vous débrouiller tout seul.
En tant que tel, il est généralement préférable de ne pas donner de références ou de pointeurs vers des attributs. Pas même les constantes !
Pour les petites valeurs, il est généralement suffisant de les passer par copie (les deux in
y out
), surtout maintenant avec la sémantique du mouvement (à l'entrée).
Pour des valeurs plus importantes, cela dépend vraiment de la situation, parfois un Proxy peut vous soulager.
Enfin, notez que pour certaines classes, avoir des membres publics n'est pas si mal. Quel serait l'intérêt d'encapsuler les membres d'une classe de type pair
? Lorsque vous vous retrouvez à écrire une classe qui n'est rien de plus qu'une collection d'attributs (sans aucun invariant), au lieu de faire du OO et d'écrire une paire getter/setter pour chacun d'eux, pensez à les rendre publics.