I\'m surprised that the code below compiles.
It seems that a class befriended to the (publicly inherited) base class can access a member of the base class provided an in
- It seems that somehow friendship is inherited and a friend class can access a member of the derived class.
In short, how isd.b_varvalid withinF::func(D& d)?
d.b_var might be misleading. To be more precise (another way to see it), b_var is not (direct) member of derived class D. Instead, the object of D contains a subobject of base class B, which has member b_var, and could be accessed by the friend F. (As we can also write d.b_var as d.B::b_var.)
$10/3 Derived classes [class.derived]:
The base-specifier-list specifies the type of the base class subobjects contained in an object of the derived class type. [ Example:
struct Base { int a, b, c; }; struct Derived : Base { int b; }; struct Derived2 : Derived { int c; };Here, an object of class
Derived2will have a subobject of classDerivedwhich in turn will have a subobject of classBase. — end example ]
And
- If the inheritance is changed to
privatethen compilation fails.
Because
class B {
int b_var;
friend class F;
};
class D: private B {
int d_var;
};
class F{
public:
void func(D &d) {
d.b_var = 5; // Fail. Can't access subobject of B
d.d_var = 5; // Fail. Can't access member of D
}
};
Then
class B {
int b_var;
};
class D: private B {
friend class F;
int d_var;
};
class F{
public:
void func(D &d) {
d.b_var = 5; // Fail. Can't access b_var of subobject of B
d.d_var = 5; // Fine.
}
};
Note that in last case, even F is friend of class D, it could access all the private/protected members of D, but not including members in subobject B, because they're not (direct) members of class D.