class A
{
int a;
public:
A (int aa) : a (aa) {} // Costruttore che inizializza a
friend void foo();
};
void foo()
{
A a_obj (5); // Normale chiamata
a_obj.a = 10; // Non sarebbe permesso in una funzione non-friend
}
Puoi mettere le dichiarazioni friend da qualsiasi parte nella definizione della classe,
perchè una ad una funzione friend non si applicano gli attributi di pubblico
o privato.
Notare che è la classe che sceglie quali funzioni avranno il permesso di
accedere direttamente ai suoi membri privati. Dopo questa dichiarazione nella
classe, non è necessario alcun altro prototipo quando definiamo la funzione.
Le funzioni Friend sono spesso usate ridefinire gli operatori.
Una funzione friend non può accedere al puntatore
this, perchè
non viene invocata su un oggetto.
Puoi usare anche una funzione membro di un'altra classe come funzione friend di una classe.
class B; // dichiarazione necessaria per evitare problemi di riferimento circolare
class A
{
void uses_class_B (B &); // Normale funzione membro
};
class B
{
friend void A::uses_class_B (B &); // dichiarazione di una funzione friend
};
In questo esempio la funzione uses_class_B della classe A, che accetta per parametro
un riferimento ad un oggetto della classe B, è friend della classe B.
class A
{
int a;
friend class B;
};
class B
{
public:
void foo();
};
B::foo()
{
A a_obj;
a_obj.a = 10; // Non sarebbe permesso se la classe B non fosse friend di A
}
Nota bene che è la classe A che sceglie quali classi hanno il diritto
di accedere ai suoi membri privati e non quest'ultime.
Una conseguenza di questo fatto è che classi amiche di classi amiche di una classe non sono classi amiche anche di quest'ultima. Vediamo un esempio per chiarire il gioco di parole:
class A
{
int a;
friend class B;
};
class B
{
int b;
friend class C;
};
class C
{
int c;
int foo()
{
B b_obj;
b_obj.b = 10; // OK
A a_obj;
a_obj.a = 10; // Rifiutata dal compilatore. Dovrebbe esserci
} // una dichiarazione di C come class friend in A.
};
In altre parole la relazione X è friend di Y non è una relazione
transitiva.
C è friend di B, B è friend di A non implica che C sia friend di A