Une fonction est lamie (friend) dune classe lorsquelle est autorisée à adresser directement les membres privés de cette classe. Pour la déclarer ainsi, il faut donner, à lintérieur de la classe, la déclaration complète de la fonction précédée du mot clé friend
. Voici un exemple simple :
class exemple { int i, j; public: exemple() { i = 0; j = 0; } friend exemple inverse(exemple); }; exemple inverse(exemple ex)// renvoie ex avec tous les bits inversés{ exemple ex2 = ex; ex2.i = ~ex2.i; // accès aux champs ex2.j = ~ex2.j; return ex;}
À part le fait quelle est amie de la classe exemple
, la fonction est parfaitement ordinaire, et peut être déclarée et définie de la même façon que toute autre.
Le terme même damie indique clairement que la fonction doit avoir un comportement décent : il faut veiller à ce quelle ne modifie pas incorrectement les membres de la classe.
Une fonction peut être amie dautant de classes que nécessaire, mais évidemment cela nest utile que lorsque la fonction utilise une instance de la classe, et plus précisément modifie un membre privé de la classe (car en général il existe des fonctions membres en ligne permettant de lire ces membres privés ou une interprétation de ceux-ci).
Notons que la « déclaration damitié » doit se faire à lintérieur de la classe. De ce fait, si lon dispose dune classe mais sans avoir la possibilité de la modifier (par exemple, dans un fichier en-tête on peut ne trouver que la déclaration dune classe sans sa définition), il nest pas possible de lui ajouter des fonctions amies. Cela nest pas une restriction du langage, mais au contraire un moyen sûr et efficace de protéger des données. De ce fait, avant de « verrouiller » une classe, on prendra soin de fournir tous les moyens daccès raisonnables (en lecture notamment) aux champs utiles, afin de permettre la création de fonctions non amies utilisant cette classe.
Lorsque cette précaution a été prise, il nest plus besoin dune fonction amie, en dépit des apparences. Par exemple, la librairie <complex.h>
fournit une classe complex
(qui est fondamentalement formée de deux nombres à virgule flottante nommés partie réelle et partie imaginaire) et un ensemble de fonctions la manipulant ; cependant, les concepteurs de la librairie nont pas implanté une opération importante sur les nombres complexes, nommée conjugaison, qui consiste simplement à changer le signe de la partie imaginaire. Est-ce à dire quil faut modifier <complex.h>
pour déclarer « amie » la fonction ayant cet effet ? Nullement, car on dispose de deux fonctions amies real
et imag
donnant les parties réelle et imaginaire dun complexe, ainsi que du constructeur complex(double, double)
qui crée un complexe à partir de ses deux parties. De ce fait, il suffit décrire une fonction normale :
inline complexe conjug(complexe c){ return complexe(real(c), -imag(c));}
Cette fonction nest pas amie de la classe complex
, mais elle naccède quà des parties publiques de celle-ci (le constructeur et les deux fonctions amies real
et imag
), il ny a donc pas de problème. On pourrait bien sûr sinquiéter : les trois appels de fonction (real
, imag
et complex
) ne vont-ils pas grever le temps dexécution de cette opération pourtant élémentaire ? Nullement, car ces trois fonctions très simples aussi sont écrites en ligne. De ce fait, lécriture c1 = conjug(c2)
; ne provoquera aucun
appel de fonction, puisque conjug
est aussi en ligne.
![]() | ![]() | Suivant ![]() |