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
friend
elaborated-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ě B
pouze 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 YourClass
soukromým členům. Přátelství není tranzitivní, takže třídy, které jsou přáteli YourOtherClass
, nemají přístup k YourClass
soukromý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
).
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é
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro