The name of a friend function or class first introduced in a friend declaration is not in the scope of the class granting friendship (also called the enclosing class) and is not a member of the class granting friendship.
The name of a function first introduced in a friend declaration is in the scope of the first nonclass scope that contains the enclosing class. The body of a function provided inside a friend declaration is handled in the same way as a member function defined within a class. Processing of the definition does not start until the end of the outermost enclosing class. In addition, unqualified names in the body of the function definition are searched for starting from the class containing the function definition.
namespace A { //the first nonclass scope
class B {
class C {
friend class D;
}
};
};
In this example, the first nonclass scope
that encloses the friend declaration of class D is
namespace A, so friend class D is
in the scope of namespace A. If the name of a friend class has been introduced before the friend declaration, the compiler searches for a class name that matches the name of the friend class beginning at the scope of the friend declaration. If the declaration of a nested class is followed by the declaration of a friend class with the same name, the nested class is a friend of the enclosing class.
class A {
public:
int f() { }
};
class B {
friend int A::f();
};
class A {
friend class B;
int a;
};
class B { };
class C : public B {
void f(A* p) {
p->a = 2; // error
}
};
The compiler does not support the statement p->a
= 2 because class C is not a friend of class A,
although C inherits from a friend of A.class A {
friend class B;
int a;
};
class B {
friend class C;
};
class C {
void f(A* p) {
p->a = 2; // error
}
};
The compiler does not accept the statement p->a
= 2 because class C is not a friend of class A,
although C is a friend of a friend of A.class X { };
void a();
void f() {
class Y { };
void b();
class A {
friend class X;
friend class Y;
friend class Z;
friend void a(); // error
friend void b();
friend void c(); // error
};
::X moocow;
X moocow2;
}
In the above example, the compiler accepts
the following statements: