Le mot-clé friend permet à une fonction ou à une autre classe d'accéder aux membres privés et protégés de la classe où friend est déclaré. Les fonctions friend peuvent être à la fois globales et des méthodes d'autres classes. Cette construction permet de mettre en œuvre des fonctions qui nécessitent un accès à l'état interne de la classe, mais qui ne sont pas logiquement liées à l'interface de cette classe.
Il est recommandé d'utiliser friend :
Attention :
Exemple :
class Box { int width; public: Box(int w): width(w) {} friend void printWidth(const Box &b); }; void printWidth(const Box &b) { std::cout << b.width << std::endl; }
Question : Une fonction friend peut-elle être virtuelle ?
Réponse fréquente : Oui, car friend est un modificateur de fonction.
Réponse correcte : Non, les fonctions friend ne peuvent pas être virtuelles, car elles ne sont pas des membres de la classe !
Exemple :
class Example { friend virtual void foo(); // Erreur de compilation : virtual ne s'applique pas à friend };
Histoire : Lors de la conception d'une bibliothèque matricielle, tous les opérateurs arithmétiques ont été faits fonctions friend pour améliorer la vitesse, mais il a été oublié de prendre en charge la constance, ouvrant excessivement l'accès aux membres privés. Plus tard, un problème est survenu — d'autres fonctions dans le projet modifiaient accidentellement l'état interne de Matrix.
Histoire : Dans un système d'entreprise, les classes utilitaires sont devenues friends les unes des autres pour partager l'accès aux membres privés. Cela a conduit à des dépendances cycliques — l'ajout d'une nouvelle fonctionnalité nécessitait de modifier toutes les classes liées. Le refactoring qui a suivi a pris des semaines.
Histoire : Pour des tests fermés, il a été décidé de faire de la classe de test une friend de la classe de production. Lorsque plusieurs ensembles de tests unitaires sont apparus, il est devenu impossible de suivre quels méthodes privées étaient réellement utilisées — les tests ont commencé à dépendre de l'implémentation interne, rendant le code difficile à maintenir.