[class.friend] (original) (raw)

11 Classes [class]

11.8 Member access control [class.access]

11.8.4 Friends [class.friend]

A friend of a class is a function or class that is given permission to name the private and protected members of the class.

A class specifies its friends, if any, by way of friend declarations.

Such declarations give special access rights to the friends, but they do not make the nominated friends members of the befriending class.

[Example 1:

The following example illustrates the differences between members and friends: class X { int a;friend void friend_set(X*, int);public: void member_set(int);};void friend_set(X* p, int i) { p->a = i; } void X::member_set(int i) { a = i; } void f() { X obj; friend_set(&obj,10); obj.member_set(10);}

— _end example_]

Declaring a class to be a friend implies that private and protected members of the class granting friendship can be named in thebase-specifiers and member declarations of the befriended class.

[Example 2: class A { class B { };friend class X;};struct X : A::B { A::B mx; class Y { A::B my; };}; — _end example_]

[Example 3: class X { enum { a=100 };friend class Y;};class Y { int v[X::a]; };class Z { int v[X::a]; }; — _end example_]

If a friend-type-specifier in a friend declaration designates a (possibly cv-qualified) class type, that class is declared as a friend; otherwise, thefriend-type-specifier is ignored.

[Example 4: class C;typedef C Ct;class E;class X1 { friend C; };class X2 { friend Ct; friend D; friend class D; };template <typename ... Ts> class R { friend Ts...;};template <class... Ts, class... Us> class R<R<Ts...>, R<Us...>> { friend Ts::Nested..., Us...;}; R<C> rc; R<C, E> rce; R<int> Ri; struct E { struct Nested; }; R<R<E>, R<C, int>> rr; — _end example_]

[Note 2:

A friend declaration refers to an entity, not (all overloads of) a name.

A member function of a classXcan be a friend of a classY.

[Example 5: class Y { friend char* X::foo(int);friend X::X(char); friend X::~X(); }; — _end example_]

— _end note_]

A function may be defined in a friend declaration of a class if and only if the class is a non-local class ([class.local]) and the function name is unqualified.

[Example 6: class M { friend void f() { } }; — _end example_]

Such a function is implicitly an inline ([dcl.inline]) function if it is attached to the global module.

[Note 3:

If a friend function is defined outside a class, it is not in the scope of the class.

— _end note_]

A member nominated by a friend declaration shall be accessible in the class containing the friend declaration.

The meaning of the friend declaration is the same whether the friend declaration appears in the private, protected, or public ([class.mem]) portion of the classmember-specification.

Friendship is neither inherited nor transitive.

[Example 7: class A { friend class B;int a;};class B { friend class C;};class C { void f(A* p) { p->a++; } };class D : public B { void f(A* p) { p->a++; } }; — _end example_]

[Example 8: void h(int);template <class T> void f2(T);namespace A { class X { friend void f(X); class Y { friend void g(); friend void h(int); friend void f2<>(int); };}; X x;void g() { f(x); } void f(X) { } void h(int) { } } using A::x;void h() { A::f(x); A::X::f(x); A::X::Y::g(); } — _end example_]

[Example 9: class X;void a();void f() { class Y;extern void b();class A { friend class X; friend class Y; friend class Z; friend void a(); friend void b(); friend void c(); }; X* px; Z* pz; } — _end example_]