50

I am confused about the meaning of access modifiers with respect to inheritance. What is the difference between inheritance involving the private, protected and public keywords?

Destructor
  • 14,123
  • 11
  • 61
  • 126
Sista
  • 887
  • 2
  • 15
  • 19
  • 9
    Where are you trying to use this protected member? What do you think protected means? – James McNellis Mar 27 '11 at 05:50
  • What other function? Can you give a minimal but complete code sample that gives the error? – Eelke Mar 27 '11 at 06:17
  • 1
    @Sista - Post the code of what you are actually trying to do. – Mahesh Mar 27 '11 at 06:22
  • @Mahesh - Thanks for responding. I understood how to proceed with Als help! – Sista Mar 27 '11 at 16:38
  • @Sista: SO is a wonderful forum to learn and most of the people are ever-willing to help just what everyone wants to see is clarity in questions, motivation and willingness to learn(attempts to write code or understand concept) rather than getting people to do them for oneself. So do remember the points when you post next time. Happy learning! :) – Alok Save Mar 27 '11 at 16:45

2 Answers2

160

what are Access Specifiers?

There are 3 access specifiers for a class/struct/Union in C++. These access specifiers define how the members of the class can be accessed. Of course, any member of a class is accessible within that class(Inside any member function of that same class). Moving ahead to type of access specifiers, they are:

Public - The members declared as Public are accessible from outside the Class through an object of the class.

Protected - The members declared as Protected are accessible from outside the class BUT only in a class derived from it.

Private - These members are only accessible from within the class. No outside Access is allowed.

An Source Code Example:

class MyClass
{
    public:
        int a;
    protected:
        int b;
    private:
        int c;
};

int main()
{
    MyClass obj;
    obj.a = 10;     //Allowed
    obj.b = 20;     //Not Allowed, gives compiler error
    obj.c = 30;     //Not Allowed, gives compiler error
}

Inheritance and Access Specifiers

Inheritance in C++ can be one of the following types:

  • Private Inheritance
  • Public Inheritance
  • Protected inheritance

Here are the member access rules with respect to each of these:

First and most important rule Private members of a class are never accessible from anywhere except the members of the same class.

Public Inheritance:

All Public members of the Base Class become Public Members of the derived class &
All Protected members of the Base Class become Protected Members of the Derived Class.

i.e. No change in the Access of the members. The access rules we discussed before are further then applied to these members.

Code Example:

Class Base
{
    public:
        int a;
    protected:
        int b;
    private:
        int c;
};

class Derived:public Base
{
    void doSomething()
    {
        a = 10;  //Allowed 
        b = 20;  //Allowed
        c = 30;  //Not Allowed, Compiler Error
    }
};

int main()
{
    Derived obj;
    obj.a = 10;  //Allowed
    obj.b = 20;  //Not Allowed, Compiler Error
    obj.c = 30;  //Not Allowed, Compiler Error

}

Private Inheritance:

All Public members of the Base Class become Private Members of the Derived class &
All Protected members of the Base Class become Private Members of the Derived Class.

An code Example:

Class Base
{
    public:
      int a;
    protected:
      int b;
    private:
      int c;
};

class Derived:private Base   //Not mentioning private is OK because for classes it  defaults to private 
{
    void doSomething()
    {
        a = 10;  //Allowed 
        b = 20;  //Allowed
        c = 30;  //Not Allowed, Compiler Error
    }
};

class Derived2:public Derived
{
    void doSomethingMore()
    {
        a = 10;  //Not Allowed, Compiler Error, a is private member of Derived now
        b = 20;  //Not Allowed, Compiler Error, b is private member of Derived now
        c = 30;  //Not Allowed, Compiler Error
    }
};

int main()
{
    Derived obj;
    obj.a = 10;  //Not Allowed, Compiler Error
    obj.b = 20;  //Not Allowed, Compiler Error
    obj.c = 30;  //Not Allowed, Compiler Error

}

Protected Inheritance:

All Public members of the Base Class become Protected Members of the derived class &
All Protected members of the Base Class become Protected Members of the Derived Class.

A Code Example:

Class Base
{
    public:
        int a;
    protected:
        int b;
    private:
        int c;
};

class Derived:protected Base  
{
    void doSomething()
    {
        a = 10;  //Allowed 
        b = 20;  //Allowed
        c = 30;  //Not Allowed, Compiler Error
    }
};

class Derived2:public Derived
{
    void doSomethingMore()
    {
        a = 10;  //Allowed, a is protected member inside Derived & Derived2 is public derivation from Derived, a is now protected member of Derived2
        b = 20;  //Allowed, b is protected member inside Derived & Derived2 is public derivation from Derived, b is now protected member of Derived2
        c = 30;  //Not Allowed, Compiler Error
    }
};

int main()
{
    Derived obj;
    obj.a = 10;  //Not Allowed, Compiler Error
    obj.b = 20;  //Not Allowed, Compiler Error
    obj.c = 30;  //Not Allowed, Compiler Error
}

Remember the same access rules apply to the classes and members down the inheritance hierarchy.


Important points to note:

- Access Specification is per-Class not per-Object

Note that the access specification C++ work on per-Class basis and not per-object basis.
A good example of this is that in a copy constructor or Copy Assignment operator function, all the members of the object being passed can be accessed.

- A Derived class can only access members of its own Base class

Consider the following code example:

class Myclass
{ 
    protected: 
       int x; 
}; 

class derived : public Myclass
{
    public: 
        void f( Myclass& obj ) 
        { 
            obj.x = 5; 
        } 
};

int main()
{
    return 0;
}

It gives an compilation error:

prog.cpp:4: error: ‘int Myclass::x’ is protected

Because the derived class can only access members of its own Base Class. Note that the object obj being passed here is no way related to the derived class function in which it is being accessed, it is an altogether different object and hence derived member function cannot access its members.


What is a friend? How does friend affect access specification rules?

You can declare a function or class as friend of another class. When you do so the access specification rules do not apply to the friended class/function. The class or function can access all the members of that particular class.

So do friends break Encapsulation?

No they don't, On the contrary they enhance Encapsulation!

friendship is used to indicate a intentional strong coupling between two entities.
If there exists a special relationship between two entities such that one needs access to others private or protected members but You do not want everyone to have access by using the public access specifier then you should use friendship.

Tharif
  • 13,794
  • 9
  • 55
  • 77
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • 7
    @Alf: Thanks Alf, I just hope the questioner learns through the answer. When i started out I had to learn all by myself and I know its hard to do so just trying to do my best. I did mark it as a FAQ answer but since Sbi removed it seems the answer is not good enough or perhaps it doesn't fit in to the idea behind FAQ. – Alok Save Mar 27 '11 at 10:31
  • 4
    Thanks a lot for the detailed explanation. I am a newbie to C++ and this really helped me to clear some concepts. I am sorry I could not respond earlier. I had to get back home from the library and only this morning I saw your response. I now have a clearer understanding on the access specifiers. Thanks once again. – Sista Mar 27 '11 at 16:36
  • 1
    The answer is quite good, but I believe that for a FAQ it is still missing as much as it gives: the meaning of `friend`, relationships with nested/member types, and more importantly a precise definition of what protected means that tackles the common misunderstanding that this should compile: `class base { protected: int x; }; struct derived : base { static void f( base& b ) { b.x = 5; } };` – David Rodríguez - dribeas Jun 17 '12 at 12:13
  • 1
    @DavidRodríguez-dribeas: When I answered this it was not meant to be a faq entry, eventually it was made one.I modified the answer to cover some important aspects you pointed out.Indeed they are important,thanks for raising them.However, I also do feel that this topic has a very wide scope and coverage and i find it difficult to cover and touch upon all the aspects. – Alok Save Jun 17 '12 at 16:59
  • 1
    As it is now, it does cover *most* of what the syntax means, it probably covers all that will be needed for most answers. For anything else, they can make their own question :) – David Rodríguez - dribeas Jun 18 '12 at 00:47
  • 1
    Wow... This is great. I don't want to look a gift horse in the mouth, but can anyone edit in how `virtual` affects inheritance? I got here by googling for that. I'll get back to the search results and edit it in myself if nobody does by the time I learn. – Michael Hoffmann Nov 06 '15 at 07:21
5

The explanation from Scott Meyers in Effective C++ might help understand when to use them:

Public inheritance should model "is-a relationship," whereas private inheritance should be used for "is-implemented-in-terms-of" - so you don't have to adhere to the interface of the superclass, you're just reusing the implementation.

jkdev
  • 11,360
  • 15
  • 54
  • 77
Ivan Vergiliev
  • 3,771
  • 24
  • 23