Nous allons partir d'un exemple assez simple. Supposons toujours notre classe point et une fonction egal qui retourne 1 si les objets passés en arguments sont égaux et -1 s'il ne le son pas. Comme la fonction egal est une fonction indépendante de toute classe elle ne peut accéder directement aux données membre des objets qui lui sont transmit en paramètres. Il faut donc à l'intérieure de la définition de la classe préciser que la fonction egal est une fonction amie(mot clé friend)de la classe point afin quelle puisse accédé directement aux données membre de la classe point:
class point { int x,y; public: point (int abs=0, int ord=0) :x(abs), y(ord){} friend int egal(point ,point); }; int egal(point a, point b) { if (a.x==b.x && a.y==b.y) return 1; else returne (-1); }
Ici la fonction egal reçoit bien deux objet a et b de type point, et elle peut accéder a leur données membre sans aucun problème.
Ici il ne s'agit plus d'une fonction indépendante mais d'une fonction membre d'une classe qui veut accéder aux données membre d'un objet d'une autre classe. La déclaration d'amitié est pareille que précédemment sauf qu'il faut indiquer à quelle classe appartient cette fonction amie. Pour cela nous utilisons l'opérateur de résolution de portée "::"
Supposons une classe A et une classe B. La classe B souhaite pouvoirs accédé aux données membre d'un objet de la classe A dans l'une de ces fonctions membre, voici le prototype de la fonction membre de B :
int fonct(A);
Au sein de la classe A elle sera déclaré ainsi :
friend int B::fonct(A);
Pour compilé convenablement la classe A, elle doit être compilé avec la déclaration de la classe B(mais pas forcément sa définition).
Rien n'empêche une fonction(membre ou indépendante) d'être amie de plusieurs classe à la fois, pour cela elle doit être déclarée amie dans chacune de ces classes.
Nous avons vu qu'une fonction membre d'une classe peut être amie d'une autre classe, mais supposons que plusieurs fonctions membre d'une classe ait besoin d'être amie avec la même classe, il serait lourd de déclaré toute ces fonctions amies. Donc C++ nous permet de déclaré une classe amie d'une autre classe. Pour cela il suffit d'introduire dans A la déclaration friend class B.
Nous savons que nous pouvons compiler séparément la définition de la déclaration d'une classe. Il en va de même pour une fonction indépendante amie d'une classe.
Mais lors de la compilation le programmeur n'est forcé de fournir la vraie fonction amie de la classe. Cette fonction dites "caméléon" peut donc a cause de l'amitié accédé directement aux données membre des objet d'une classe. Mais ceci est forcément une action délibérée......