Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a friend class object access base class private members on a derived class object?

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 instance of the derived class.

If the inheritance is changed to private then compilation fails.

In short, how is d.b_var valid within F::func(D& d)?

#include <iostream>
#include <string>
using namespace std;

class B{
    int b_var;
    friend class F;
};

class D: public B{
    int d_var;
};

class F{
    public:
        void func(D &d){
            d.b_var = 5; 
        }
};

int main()
{
    cout<<"fine";
}
like image 528
Hemant Sharma Avatar asked Sep 08 '16 06:09

Hemant Sharma


People also ask

Can derived class access private members of base?

Private members of the base class cannot be used by the derived class unless friend declarations within the base class explicitly grant access to them.

Can a friend function access a derived class?

If a base class has a friend function, then the function doesn't become a friend of the derived class(es). For example, the following program prints an error because the show() which is a friend of base class A tries to access private data of derived class B.

Can base class access members of derived class give reasons?

Explanation: A base class pointer can point to a derived class object, but we can only access base class member or virtual functions using the base class pointer because object slicing happens when a derived class object is assigned to a base class object.

Can a object of a derived class Cannot access private members of base class?

On the other hand, multiple levels of inheritance means a class has been derived from a base class and the base class itself has been derived from another base class. Multiple inheritance is not permitted in C#.NET. 2. An object of a derived class cannot access private members of base class.


1 Answers

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?

like image 146
sameerkn Avatar answered Oct 27 '22 21:10

sameerkn