Funzioni membro di classi e classi di tipo friend
Le funzioni membro di classe possono essere dichiarate come friend in altre classi. Si consideri l'esempio seguente:
// classes_as_friends1.cpp
// compile with: /c
class B;
class A {
public:
int Func1( B& b );
private:
int Func2( B& b );
};
class B {
private:
int _b;
// A::Func1 is a friend function to class B
// so A::Func1 has access to all members of B
friend int A::Func1( B& );
};
int A::Func1( B& b ) { return b._b; } // OK
int A::Func2( B& b ) { return b._b; } // C2248
Nell'esempio precedente, solo alla funzione A::Func1( B& ) viene concesso l'accesso Friend alla classe B. Di conseguenza, l'accesso al membro privato _b è corretto in Func1 di classe A ma non in Func2.
Una classe friend è una classe in cui tutte le funzioni membro sono funzioni Friend di una classe, ovvero, le cui funzioni membro hanno accesso agli altri membri privati e protetti della classe. Si supponga che la dichiarazione friend nella classe B sia stata:
friend class A;
In tal caso, a tutte le funzioni membro nella classe A sarebbe stato concesso l'accesso Friend alla classe B. Il codice seguente è un esempio di una classe Friend:
// classes_as_friends2.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
class YourClass {
friend class YourOtherClass; // Declare a friend class
public:
YourClass() : topSecret(0){}
void printMember() { cout << topSecret << endl; }
private:
int topSecret;
};
class YourOtherClass {
public:
void change( YourClass& yc, int x ){yc.topSecret = x;}
};
int main() {
YourClass yc1;
YourOtherClass yoc1;
yc1.printMember();
yoc1.change( yc1, 5 );
yc1.printMember();
}
L'accesso Friend non è reciproco a meno che non venga specificato in modo esplicito come tale. Nell'esempio precedente, le funzioni membro di YourClass non possono accedere ai membri privati di YourOtherClass.
Un tipo gestito non può avere nessuna funzione Friend, classe Friend o interfaccia Friend.
L'accesso Friend non è ereditato, pertanto classi derivate da YourOtherClass non possono accedere a membri privati di YourClass. L'accesso Friend non è transitivo, pertanto classi che rappresentano elementi friend di YourOtherClass non possono accedere a membri privati di YourClass.
Nella figura seguente vengono illustrate quattro dichiarazioni di classe: Base, Derived, aFriend e anotherFriend. Solo la classe aFriend ha accesso diretto ai membri privati di Base (e a tutti i membri che Base possa aver ereditato).
Implicazioni di relazioni friend