If you reference a protected nonstatic member
x of
a base class
A in a friend or a member function of
a derived class
B, you must access
x through
a pointer to, reference to, or object of a class derived from
A.
However, if you are accessing
x to create a pointer
to member, you must qualify
x with a nested name
specifier that names the derived class
B. The following
example demonstrates this:
class A {
public:
protected:
int i;
};
class B : public A {
friend void f(A*, B*);
void g(A*);
};
void f(A* pa, B* pb) {
// pa->i = 1;
pb->i = 2;
// int A::* point_i = &A::i;
int A::* point_i2 = &B::i;
}
void B::g(A* pa) {
// pa->i = 1;
i = 2;
// int A::* point_i = &A::i;
int A::* point_i2 = &B::i;
}
void h(A* pa, B* pb) {
// pa->i = 1;
// pb->i = 2;
}
int main() { }
Class
A contains one protected
data member, an integer
i. Because
B derives
from
A, the members of
B have access
to the protected member of
A. Function
f() is
a friend of class
B:
- The compiler would not allow pa->i = 1 because pa is
not a pointer to the derived class B.
- The compiler would not allow int A::* point_i = &A::i because i has
not been qualified with the name of the derived class B.
Function
g() is a member function of class
B.
The previous list of remarks about which statements the compiler would
and would not allow apply for
g() except for the
following:
- The compiler allows i = 2 because it is equivalent
to this->i = 2.
Function
h() cannot access any of the protected
members of
A because
h() is neither
a friend or a member of a derived class of
A.