Share via


friend (C++)

V některých případech je užitečné, aby třída udělila členům přístup k funkcím, které nejsou členy třídy, nebo všem členům v samostatné třídě. Tyto bezplatné funkce a třídy se označují jako přátelé označené klíčovým slovem friend . Pouze implementátor třídy může deklarovat, kdo jsou jeho přátelé. Funkce nebo třída se nemůže deklarovat jako přítel žádné třídy. V definici třídy použijte friend klíčové slovo a název nečlenné funkce nebo jiné třídy k udělení přístupu k soukromým a chráněným členům vaší třídy. V definici šablony lze parametr typu deklarovat jako .friend

Syntaxe

friend-declaration:
friend function-declaration
friend function-definition
friendelaborated-type-specifier;;
friend simple-type-specifier ;
friend typename-specifier ;

friend Prohlášení

Pokud deklarujete friend funkci, která nebyla dříve deklarována, je tato funkce exportována do nadřazeného oboru, který není třídami.

Funkce deklarované v friend deklaraci se považují za deklarované pomocí klíčového extern slova. Další informace najdete na webu extern.

Přestože lze funkce s globálním oborem deklarovat jako friend funkce před jejich prototypy, členské funkce nelze deklarovat jako friend funkce před vznikem jejich úplné deklarace třídy. Následující kód ukazuje, jak taková deklarace selže:

class ForwardDeclared;   // Class name is known.
class HasFriends
{
    friend int ForwardDeclared::IsAFriend();   // C2039 error expected
};

Předchozí příklad zadá název ForwardDeclared třídy do oboru, ale úplná deklarace (konkrétně část, která deklaruje funkci IsAFriend), není známá. deklarace friend ve třídě HasFriends generuje chybu.

V jazyce C++11 existují dvě formy deklarací přítele pro třídu:

friend class F;
friend F;

První formulář zavádí novou třídu F, pokud nebyla nalezena žádná existující třída podle názvu v nejvnitřnějším oboru názvů. C++11: Druhý formulář nezavádí novou třídu; lze ji použít, pokud již byla třída deklarována, a musí být použita při deklarování parametru typu šablony nebo typedef jako friend.

Použijte friend class F , když odkazovaný typ ještě nebyl deklarován:

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

Pokud používáte friend typ třídy, který nebyl deklarován, dojde k chybě:

namespace NS
{
    class M
    {
        friend F; // error C2433: 'NS::F': 'friend' not permitted on data declarations
    };
}

V následujícím příkladu F odkazuje na třídu, friend F která je deklarována mimo rozsah NS.

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

Slouží friend F k deklaraci parametru šablony jako přítele:

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

Slouží friend F k deklaraci definice typedef jako přítele:

class Foo {};
typedef Foo F;

class G
{
    friend F; // OK
    friend class F // Error C2371 -- redefinition
};

Je-li třeba deklarovat dvě třídy, které jsou navzájem spřáteleny, celá druhá třída musí být zadána jako přátelská třída první třídy. Důvod tohoto omezení je, že kompilátor má dostatek informací pro deklarování jednotlivých přátelských funkcí pouze v případě, kdy je deklarována druhá třída.

Poznámka

Ačkoli celá druhá třída musí být přátelskou třídou první třídy, je možné vybrat, které funkce první třídy budou přáteli druhé třídy.

friend – funkce

Funkce friend je funkce, která není členem třídy, ale má přístup k soukromým a chráněným členům třídy. Přátelské funkce nejsou považovány za členy třídy; jsou to normální externí funkce, kterým jsou udělena zvláštní přístupová oprávnění. Přátelé nejsou v oboru předmětu a nejsou voláni pomocí operátorů výběru členů (. a ->), pokud nejsou členy jiné třídy. Funkce friend je deklarována třídou, která uděluje přístup. Deklarace friend může být umístěna kdekoli v deklaraci třídy. Na klíčová slova řízení přístupu to nemá vliv.

Následující příklad ukazuje třídu Point a spřátelenou funkci ChangePrivate. Funkce friend má přístup k privátnímu datovému členu objektu Point , který přijímá jako parametr.

// 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
}

Členové předmětu jako přátelé

Členské funkce třídy mohou být v jiných třídách deklarovány jako přátelské funkce. Představte si následující příklad:

// 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

V předchozím příkladu je udělen friend přístup ke třídě Bpouze funkce A::Func1( B& ) . Proto je přístup k soukromému členu _b ve Func1 třídě A správný, ale nikoli v Func2.

friend Třída je třída, jejíž členské funkce jsou friend funkcemi třídy, tj. jejíž členské funkce mají přístup k soukromým a chráněným členům druhé třídy. Předpokládejme, že by deklarace friend v třídě B byla:

friend class A;

V takovém případě by všem členským funkcím ve třídě A byl udělen friend přístup ke třídě B. Následující kód je příkladem friend třídy:

// 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();
}

Přátelství není vzájemné, pokud není výslovně uvedeno. V předchozím příkladu nemají členské funkce YourClass přístup k soukromým členům YourOtherClass.

Spravovaný typ (v C++/CLI) nemůže mít žádné friend funkce, friend třídy ani friend rozhraní.

Přátelství není zděděno, což znamená, že třídy odvozené z YourOtherClass nemohou získat přístup k YourClasssoukromým členům. Přátelství není tranzitivní, takže třídy, které jsou přáteli YourOtherClass , nemají přístup k YourClasssoukromým členům.

Následující obrázek znázorňuje čtyři deklarace třídy: Base, Derived, aFriend a anotherFriend. Pouze třída aFriend má přímý přístup k soukromým členům Base (a ke všem členům, které byly zděděny Base).

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

Diagram znázorňuje, že třída jinýFriend nemá přátelský vztah se základní třídou, kterou přátelé třídy aFriend. Třída aFriend je přátelská podle třídy Base, ale nemá přátelský vztah s třídou Odvozené, i když třída Odvozená dědí ze Base. To ukazuje, že dědičnost neznamená, že odvozená třída má stejné přátele jako základní třída.

Vložené friend definice

Známé funkce lze definovat (dané tělo funkce) uvnitř deklarací tříd. Tyto funkce jsou vložené funkce. Podobně jako vložené funkce členů se chovají, jako by byly definovány ihned po zobrazení všech členů třídy, ale před uzavřením oboru třídy (na konci deklarace třídy). Známé funkce definované uvnitř deklarací třídy jsou v oboru nadřazené třídy.

Viz také

Klíčová slova