Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Unter bestimmten Umständen ist es sinnvoll, einer Klasse Zugriff auf Funktionen auf Memberebene zu gewähren, die nicht Mitglieder der Klasse oder alle Mitglieder in einer separaten Klasse sind. Diese kostenlosen Funktionen und Klassen werden als Friends bezeichnet, die durch das friend
Schlüsselwort gekennzeichnet sind. Nur der Klassenimplementierer kann seine „Friends“ deklarieren. Eine Funkion oder Klasse kann sich nicht selbst als „Friend“ einer Klasse deklarieren. Verwenden Sie in einer Klassendefinition das friend
-Schlüsselwort und den Namen einer Nichtmemberfunktion oder einer anderen Klasse, um ihr Zugriff auf die privaten und geschützten Member Ihrer Klasse zu gewähren. In einer Vorlagendefinition kann ein Typparameter als friend
deklariert werden.
Syntax
friend-declaration
:
friend
function-declaration
friend
function-definition
friend
elaborated-type-specifier
;
;
friend
simple-type-specifier
;
friend
typename-specifier
;
friend
Deklarationen
Wenn Sie eine friend
-Funktion deklarieren, die zuvor nicht deklariert wurde, wird diese Funktion in den einschließenden Nichtklassenbereich exportiert.
Die Funktionen, die in einer friend
-Deklaration deklariert sind, werden so behandelt, als ob sie mithilfe des extern
-Schlüsselworts deklariert worden wären. Weitere Informationen finden Sie unter extern
.
Obwohl Funktionen mit globalem Gültigkeitsbereich als friend
Funktionen vor ihrem Prototypen deklariert werden können, können Memberfunktionen nicht als friend
Funktionen vor der Darstellung ihrer vollständigen Klassendeklaration deklariert werden. Der folgende Code zeigt, wie eine solche Deklaration fehlschlägt:
class ForwardDeclared; // Class name is known.
class HasFriends
{
friend int ForwardDeclared::IsAFriend(); // C2039 error expected
};
Im vorhergehenden Beispiel wird der Klassenname ForwardDeclared
in den Bereich eingegeben. Die vollständige Deklaration (besonders der Teil, in der die Funktion als IsAFriend
deklariert wird) ist jedoch nicht bekannt. Daher wird von der friend
-Deklaration in der Klasse HasFriends
ein Fehler generiert.
In C++11 gibt es zwei Formen von Friend-Deklarationen für eine Klasse:
friend class F;
friend F;
Das erste Formular führt eine neue Klasse F ein, wenn im innersten Namespace keine vorhandene Klasse mit diesem Namen gefunden wurde. C++11: Das zweite Formular führt keine neue Klasse ein. Sie kann verwendet werden, wenn die Klasse bereits deklariert wurde, und sie muss beim Deklarieren eines Vorlagentypparameters oder ein typedef
als friend
verwendet werden.
friend class F
verwenden, wenn der referenzierte Typ noch nicht deklariert wurde:
namespace NS
{
class M
{
friend class F; // Introduces F but doesn't define it
};
}
Wenn Sie friend
mit einem Klassentyp verwenden, der nicht deklariert wurde, tritt ein Fehler auf:
namespace NS
{
class M
{
friend F; // error C2433: 'NS::F': 'friend' not permitted on data declarations
};
}
Im folgenden Beispiel bezieht sich friend F
auf die F
Klasse, die außerhalb des Bereichs von NS deklariert wird.
class F {};
namespace NS
{
class M
{
friend F; // OK
};
}
friend F
zum Deklarieren eines Vorlagenparameters als Friend benutzen:
template <typename T>
class my_class
{
friend T;
//...
};
friend F
zum Deklarieren einer Typedef als Friend benutzen:
class Foo {};
typedef Foo F;
class G
{
friend F; // OK
friend class F // Error C2371 -- redefinition
};
Um zwei befreundete Klassen zu deklarieren, muss die gesamte zweite Klasse als Friend der ersten Klasse angegeben werden. Diese Einschränkung besteht, weil der Compiler über genügend Informationen verfügt, um einzelne Friend-Funktionen nur an der Stelle zu deklarieren, in der die zweite Klasse deklariert wird.
Hinweis
Obwohl die gesamte zweite Klasse Friend der ersten Klasse sein muss, können Sie auswählen, welche Funktionen in der ersten Klasse Friends der zweiten Klasse sind.
friend-Funktionen
Eine friend
-Funktion ist eine Funktion, die kein Member einer Klasse ist, jedoch Zugriff auf private und geschützte Member der Klasse hat. Friend-Funktionen gelten nicht als Klassenmember. Es sind normale externe Funktionen, denen spezielle Zugriffsrechte gewährt werden. Friends befinden sich nicht im gültigen Bereich der Klasse und werden nicht mit Memberauswahloperatoren aufgerufen (. und ->), außer sie sind Member einer anderen Klasse. Eine friend
-Funktion wird von der Klasse deklariert, die Zugriff gewährt. Die Deklaration friend
kann überall in der Klassendeklaration platziert werden. Sie wird nicht durch die Schlüsselwörter der Zugriffssteuerung beeinflusst.
Das folgende Beispiel zeigt eine Point
-Klasse und die Friend-Funktion ChangePrivate
. Die Funktion friend
hat Zugriff auf den privaten Datenmember des Objekts Point
, welches es als Parameter erhält.
// friend_functions.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
class Point
{
friend void ChangePrivate( Point & );
public:
Point( void ) : m_i(0) {}
void PrintPrivate( void ){cout << m_i << endl; }
private:
int m_i;
};
void ChangePrivate ( Point &i ) { i.m_i++; }
int main()
{
Point sPoint;
sPoint.PrintPrivate();
ChangePrivate(sPoint);
sPoint.PrintPrivate();
// Output: 0
1
}
Klassenmember als „Friends“
Klassenmemberfunktionen können in anderen Klassen als "Friends" deklariert werden. Betrachten Sie das folgende Beispiel:
// 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
Im vorherigen Beispiel wird nur der A::Func1( B& )
-Funktion friend
Zugriff auf die B
-Klasse gewährt. Daher ist der Zugriff auf den privaten Member _b
in Func1
der Klasse A
richtig, jedoch nicht in Func2
.
Bei der friend
-Klasse handelt es sich um eine Klasse, deren sämtliche Memberfunktionen friend
-Funktionen einer Klasse sind, d. h. deren Memberfunktionen Zugriff auf die privaten und geschützten Member der anderen Klasse haben. Angenommen, die friend
-Deklaration in der B
-Klasse lautete:
friend class A;
In diesem Fall wären allen Memberfunktionen in der A
-Klasse friend
-Zugriff auf die B
-Klasse gewährt worden. Der folgende Code ist ein Beispiel für eine friend
Klasse:
// 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();
}
Die Friendship-Klasse wurde nicht gegenseitig festgelegt, es sei denn, sie wurde explizit als solche angegeben. Im obigen Beispiel können Memberfunktionen von YourClass
nicht auf die privaten Member von YourOtherClass
zugreifen.
Ein verwalteter Typ (in C++/CLI) kann keine friend
Funktionen, friend
Klassen oder friend
Schnittstellen enthalten.
Die Friendship-Klasse wird nicht vererbt. Dies bedeutet, dass die von YourOtherClass
abgeleiteten Klassen nicht auf die privaten Member von YourClass
zugreifen können. Die Friendship-Klasse ist nicht transitiv. Daher können Klassen, die Friends von YourOtherClass
sind, nicht auf die privaten Member von YourClass
zugreifen.
Die folgende Abbildung zeigt vier Klassendeklarationen: Base
, Derived
, aFriend
und anotherFriend
. Nur die aFriend
-Klasse hat direkten Zugriff auf die privaten Member der Base
-Klassendeklaration (und auf alle Member, die Base
möglicherweise geerbt hat).
Das Diagramm zeigt, dass Klasse anotherFriend keine Friend-Beziehung mit der Klassenbasis hat, die Klasse aFriend befreundet. "Class aFriend" wird von der Klassenbasis angefreundet, hat aber keine Friend-Bbeziehung mit der abgeleiteten Klasse, obwohl die abgeleitete Klasse von Base erbt. Dies zeigt, dass die Vererbung nicht impliziert, dass die abgeleitete Klasse die gleichen Friends wie die Basisklasse hat.
Inlinedefinitionen friend
Friend-Funktionen können innerhalb von Klassendeklarationen definiert werden (einem Funktionstext). Diese Funktionen sind Inlinefunktionen. Wie Memberinlinefunktionen verhalten sie sich, als wären sie sofort definiert worden, nachdem alle Klassenmember angezeigt wurden, jedoch bevor der Klassengültigkeitsbereich geschlossen wurde (Ende der Klassendeklaration). Friend-Funktionen, die innerhalb von Klassendeklarationen definiert sind, befinden sich im Bereich der eingeschlossenen Klasse.