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?