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
Object of class D is composed of 2 separate parts :
part containing members of B
part containing members of D
That why the concept of object slicing works when we do:
D objD;
B objB = objD;
Now we can access from inside object of class D, the part containing members of B via objB. Compiler remembers or can distinguish between the two parts inside class D. So compiler know what is being accessed via what.
The statement friend class F; inside class B simply tells that member functions of class F can accesses the private, protected and public members of class B. That is, for member functions of class F all the members of class B are public.
Actually, inside every class there are three sections w.r.t accessibility:
public
protected
private
So when we declare some class B:
class B
{
public:
int a;
protected:
int b;
public:
int c;
};
then following 3 sections get created inside class B as shown above.
Now when we declare some class F to be a friend of class B:
class B
{
friend class F;
private:
int a;
protected:
int b;
public:
int c;
};
then the compiler creates the sections as follows:
class B
{
friend class F;
private:
int a;
protected:
int b;
public:
int c;
//int a; only for member functions of class F
//int b; only for member functions of class F
};
Note that int a; and int b; are now public for member functions of class F.
Now when class D is derived publicly from class B then the public section of class B becomes public section of class D. Similary, the protected section of class B becomes protected section of class D. Therefore, the public section part of class B can be accessed via object of class D. And since B::a; and B::b; are in public section for members functions of class F, therefore B::a and B::b can be accessed via object of class D. Also note that although after derivation int a; and int b; become members of class D, still compiler is able to distinguish them and considers them a part of class B.
Now when class D is derived privately from class B then the public section of class B becomes private section of class D. Similary, the protected section of class B becomes protected section of class D. Therefore, now the public section part inside of class B cannot be accessed via object of class D. Recall that in class B, B::a; and B::b; are originally in public section for members functions of class F but after private derivation, the members of class B i.e B::a and B::b are now in private section of class D. Therefore, B::a and B::b cannot be accessed via object of class D. Also note that although after derivation int a; and int b; become members of class D, still compiler is able to distinguish them and considers them a part of class B. After derivation the accessibility and rules of some members of class B have changed.
Since this question somewhat relates to effect of public, protected and private derivation, therefore for completeness please see:
Why can a derived class not access a protected member of its base class through a pointer to base?