friend (C++)

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 Freunde bezeichnet, die durch die friend Schlüsselwort (keyword) gekennzeichnet sind. Nur der Klassenimplementierer kann seine „Friends“ deklarieren. Eine Funktion oder Klasse kann sich nicht als Freund einer Klasse deklarieren. Verwenden Sie in einer Klassendefinition die friend Schlüsselwort (keyword) und den Namen einer Nichtemberfunktion oder einer anderen Klasse, um ihm Zugriff auf die privaten und geschützten Member Ihrer Klasse zu gewähren. In einer Vorlagendefinition kann ein Typparameter als ein friend.

Syntax

friend-declaration:
friend function-declaration
friend function-definition
friendelaborated-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 eingeschlossenen Nichtklassenbereich exportiert.

In einer friend Deklaration deklarierte Funktionen werden so behandelt, als ob sie mithilfe der extern Schlüsselwort (keyword) deklariert wurden. Weitere Informationen finden Sie unter extern.

Obwohl Funktionen mit globalem Bereich vor ihren Prototypen als friend Funktionen deklariert werden können, können Memberfunktionen nicht vor der Darstellung ihrer vollständigen Klassendeklaration als friend Funktionen 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 vorherigen Beispiel wird der Klassenname ForwardDeclared in den Bereich eingegeben, die vollständige Deklaration (insbesondere der Teil, der die Funktion IsAFrienddeklariert) ist jedoch nicht bekannt. die friend Deklaration in der Klasse HasFriends generiert einen Fehler.

In C++11 gibt es zwei Formen von Freunddeklarationen 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 eines Als-Typs typedeffriendverwendet werden.

Wird verwendet friend class F , wenn der referenzierte Typ noch nicht deklariert wurde:

namespace NS
{
    class M
    {
        friend class F;  // Introduces F but doesn't define it
    };
}

Wenn Sie einen Klassentyp verwenden friend , 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 auf die Klasse, friend F die F außerhalb des Bereichs von NS deklariert wird.

class F {};
namespace NS
{
    class M
    {
        friend F;  // OK
    };
}

Dient friend F zum Deklarieren eines Vorlagenparameters als Freund:

template <typename T>
class my_class
{
    friend T;
    //...
};

Dient friend F zum Deklarieren einer Typedef als Freund:

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 Mitglied einer Klasse ist, aber Zugriff auf die privaten und geschützten Member der Klasse hat. Freundesfunktionen werden nicht als Klassenmitglieder betrachtet; sie sind normale externe Funktionen, die speziellen Zugriffsberechtigungen gewährt werden. Freunde befinden sich nicht im Bereich des Kurses, und sie werden nicht mit den Memberauswahloperatoren (und ->) aufgerufen, es sei denn, sie sind Mitglieder einer anderen Klasse. Eine friend Funktion wird von der Klasse deklariert, die Zugriff gewährt. Die friend Deklaration kann an einer beliebigen Stelle in der Klassendeklaration platziert werden. Es ist nicht von der Zugriffssteuerung Schlüsselwort (keyword) betroffen.

Das folgende Beispiel zeigt eine Point-Klasse und die Friend-Funktion ChangePrivate. Die friend Funktion hat Zugriff auf das private Datenelement des Objekts, das Point es als Parameter empfängt.

// 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 Zugriff auf die Funktion A::Func1( B& ) auf die Klasse Bgewährtfriend. Daher ist der Zugriff auf das private Mitglied _b in der Klasse A korrekt, aber nicht in Func2Func1 .

Eine friend Klasse ist eine Klasse, deren Memberfunktionen Funktionen einer Klasse sind friend , 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 hätten alle Memberfunktionen in der Klasse A Zugriff auf die Klasse Berhaltenfriend. 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();
}

Freundschaft ist nicht gegenseitig, es sei denn, explizit als solche angegeben. Im obigen Beispiel können Memberfunktionen von YourClass nicht auf die privaten Mitglieder von YourOtherClass.

Ein verwalteter Typ (in C++/CLI) kann keine Funktionen, friend Klassen oder friend Schnittstellen enthaltenfriend.

Freundschaft wird nicht geerbt, was bedeutet, dass von klassen abgeleitete YourOtherClass Klassen nicht auf private Mitglieder zugreifen YourClasskönnen. Freundschaft ist nicht transitiv, sodass Klassen, von YourOtherClass denen Freunde sind, nicht auf private Mitglieder zugreifen YourClasskönnen.

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).

A diagram that shows the derivation implications of a friend relationship.

Das Diagramm zeigt, dass klasse anotherFriend keine Freundbeziehung mit der Klassenbasis hat, die freunde klasse aFriend. "Class aFriend" wird von der Klassenbasis angefreundet, hat aber keine Freundesbeziehung mit der abgeleiteten Klasse, obwohl die abgeleitete Klasse von Base erbt. Dies zeigt, dass die Vererbung nicht impliziert, dass die abgeleitete Klasse die gleichen Freunde 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 so, als ob sie unmittelbar nach dem Anzeigen aller Klassenmember definiert wurden, aber bevor der Klassenbereich geschlossen wird (am Ende der Klassendeklaration). Friend-Funktionen, die innerhalb von Klassendeklarationen definiert sind, befinden sich im Bereich der eingeschlossenen Klasse.

Siehe auch

Schlüsselwörter