ProgrammationDéveloppeur C++

Qu'est-ce que 'friend' en C++ ? Dans quels cas est-il recommandé d'utiliser des fonctions ou des classes friend, et quelles subtilités de sécurité et de conception cela soulève-t-il ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

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 :

  • Pour la mise en œuvre d'opérateurs de comparaison, d'opérateurs mathématiques (operator<<, operator==, etc.), lorsque les fonctions doivent accéder aux membres privés de deux objets.
  • Lorsque la fonction externe n'est pas logiquement une méthode de la classe, mais doit implémenter une partie de son comportement.
  • Pour un lien étroit entre les classes travaillant ensemble (par exemple, l'accès aux données privées des objets internes voisins).

Attention :

  • L'attribution de fonctions friend ouvre l'accès aux données privées et viol les principes de l'encapsulation.
  • Un usage abusif de friend peut conduire à une augmentation des dépendances dans le code et à un affaiblissement de la sécurité.

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 piége de la réalité

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 };

Exemples d'erreurs réelles dues à une méconnaissance des subtilités du sujet


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.