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 the
base-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]
[
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 class
X
can be a friend of
a class
Y. [
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 class
member-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]