tags:

views:

4046

answers:

16

i looked in SO and couldn't find a good description regarding the difference between public, private and protected C++ inheritance. All the questions were assuming an specific case.

+17  A: 
Doug T.
Better say "public: the inheritance will be seen by everyone". protected: the inheritance will only be seen by derived classes and friends", "private: the inheritance will only be seen by the class itself and friends". This is different from your wording, since not only the members can be invisible, but also the IS-A relation can be invisible.
Johannes Schaub - litb
The one time I used private inheritance was to do Just what Doug T describes i.e "you want to use the public interface in the derived class, but don't want the user of the derived class to have access to that interface". I basically used it to seal off the old interface and expose another one through the derived class.
Rich
+22  A: 

To answer that question, I'd like to describe member's accesors first on my own words. If you already know this, goto next.

There are three accesors that I'm aware of: public, protected and private.

Let:

class Base {
    public:
        int publicMember;
    private:
        int privateMember;
    protected:
        int protectedMember;
};
  • Everything which is aware of Base, is also aware that Base contains publicMember.
  • Only the children (and their children) are aware that Base contains protectedMember.
  • No one but Base is aware of privateMember.

By "been aware", I mean "acknowledge the existence of, thus, it can be access it".

next:

The same happens with public, private and protected inheritance. Let's have a class Base and a class Child which inherits from Base.

  • Shall such inheritance be public, everything which is aware of Base and Child, is also aware that Child inherits from Base.
  • Shall such inheritance be protected, only Child (and its children), is aware that itself inherits from Base.
  • Shall such inheritance be private, no one other than Child is aware of such inheritance.
Anzurio
i find this to be the better answer but i dunno to accept it since has less votes.
Shikiyo
+1 for a good answer. While Doug T.'s answer wasn't wrong, it was a bit vague. This one seems to explain the concept more thoroughly
Josh E
this is the better answer :) +1
Doug T.
It took both answers for me to get the whole picture -- it's nice to have Doug's explanation of what the practical implications are
mikeh
you almost got -1 for using goto.. ;)But good answer.
bobobobo
A: 

It's essentially the access protection of the public and protected members of the base class in the derived class. With public inheritance, the derived class can see public and protected members of the base. With private inheritance, it can't. With protected, the derived class and any classes derived from that can see them.

Dan Olson
+1  A: 

Protected data members can be accessed by any classes that inherit from your class. Private data members, however, cannot. Let's say we have the following:

class MyClass {
    private:
        int myPrivateMember;    // lol
    protected:
        int myProtectedMember;
};

From within your extension to this class, referencing this.myPrivateMember won't work. However, this.myProtectedMember will. The value is still encapsulated, so if we have an instantiation of this class called myObj, then myObj.myProtectedMember won't work, so it is similar in function to a private data member.

Andrew Noyes
Great comment :)
e.James
A: 

Summary:

  • Private: no one can see it except for within the class
  • Protected: Private + derived classes can see it
  • Public: the world can see it

When inheriting, you can (in some languages) change the protection type of a data member in certain direction, e.g. from protected to public.

Roee Adler
A: 

Some insights can be found here. This site will be your friend in case of any other C++ related question.

Jasiu
A: 

Herb Sutter had some good coverage on this topic: part 1, part 2.

Nikolai N Fetissov
A: 

In addition to all these, let me add that in 95% of the cases the public inheritance is what best suits to your application.

Sergio
A: 

Well, I think this describes the relevant concepts pretty well.

KB22
+2  A: 

If you inherit publicly from another class, everybody knows you are inheriting and you can be used polymorphically by anyone through a base class pointer.

If you inherit protectedly only your children classes will be able to use you polymorphically.

If you inherit privately only yourself will be able to execute parent class methods.

Which basically symbolizes the knowledge the rest of the classes have about your relationship with your parent class

Arkaitz Jimenez
Thanks!!! Much clearer now.
Giuseppe
+10  A: 
class A 
{
public:
    int x;
protected:
    int y;
private:
    int z;
};

class B : public A
{
    // x is public
    // y is protected
    // z is not accessible from B
};

class C : protected A
{
    // x is protected
    // y is protected
    // z is not accessible from C
};

class D : private A
{
    // x is private
    // y is private
    // z is not accessible from D
};

IMPORTANT NOTE: Classes B, C and D are contains x, y and z. It is just question of access.

About usage of protected and private inheritance you could read here.

Kirill V. Lyadvinsky
Is private correct? Would the public members not be accessable from D, just not from outside D or D's derived classes?
Dan
For class D, x is private, y is private and z is not accessible.
Bojan Resnik
Thats what I thought. Maybe I shoulda not said anything and not deleted my comment and vote whored :-D +1 anyway, for an easy to follow answer.
Dan
@Dan, I noticed that just before you comment :) Sometimes I press Post button too fast. But there is edit link that helps me ;)
Kirill V. Lyadvinsky
A: 

Public inheritance models an IS-A relationship. With

class B {};
class D : public B {};

every D is a B.

Private inheritance models an IS-IMPLEMENTED-USING relationship (or whatever that's called). With

class B {};
class D : private B {};

a D is not a B, but every D uses its B in its implementation. Private inheritance can always be eliminated by using containment instead:

class B {};
class D {
  private: 
    B b_;
};

This D, too, can be implemented using B, in this case using its b_. Containment is a less tight coupling between types than inheritance, so in general it should be preferred. Sometimes using containment instead of private inheritance is not as convenient as private inheritance. Often that's a lame excuse for being lazy.

I don't think anyone knows what protected inheritance models. At least I haven't seen any convincing explanation yet.

sbi
+1  A: 

Limiting the visibility of inheritance will make code not being able to see that some class inherits another class: Implicit conversions from the derived to the base won't work, and static_cast from the base to the derived won't work either.

Only members/friends of a class can see private inheritance, and only members/friends and derived classes can see protected inheritance.

public inheritance

  1. IS-A inheritance. A button is-a window, and anywhere where a window is needed, a button can be passed too.

    class button : public window { };
    

protected inheritance

  1. Protected implemented-in-terms-of. Rarely useful. Used in boost::compressed_pair to derive from empty classes and save memory using empty base class optimization (example below doesn't use template to keep being at the point):

    struct empty_pair_impl : protected empty_class_1 
    { non_empty_class_2 second; };
    
    
    struct pair : private empty_pair_impl {
      non_empty_class_2 &second() {
        return this->second;
      }
    
    
      empty_class_1 &first() {
        return *this; // notice we return *this!
      }
    };
    

private inheritance

  1. Implemented-in-terms-of. The usage of the base class is only for implementing the derived class. Useful with traits and if size matters (empty traits that only contain functions will make use of the empty base class optimization). Often containment is the better solution, though. The size for strings is critical, so it's an often seen usage here

    template<typename StorageModel>
    struct string : private StorageModel {
    public:
      void realloc() {
        // uses inherited function
        StorageModel::realloc();
      }
    };
    


public member

  1. Aggregate

    class pair {
    public:
      First first;
      Second second;
    };
    
  2. Accessors

    class window {
    public:
        int getWidth() const;
    };
    

protected member

  1. Providing enhanced access for derived classes

    class stack {
    protected:
      vector<element> c;
    };
    
    
    class window {
    protected:
      void registerClass(window_descriptor w);
    };
    

private member

  1. Keep implementation details

    class window {
    private:
      int width;
    };
    


Note that C-style casts purposely allows casting a derived class to a protected or private base class in a defined and safe manner and to cast into the other direction too. This should be avoided at all costs, because it can make code dependent on implementation details - but if necessary, you can make use of this technique.

Johannes Schaub - litb
A: 

private: the private members of a base class can only be accessed by members of that base class .

public: the public members of a base class can be accessed by members of that base class, members of its derived class as well as the members which are outside the base class and derived class.

protected: the protected members of a base class can be accessed by members of base class as well as members of its derived class.

in short :

private: base

protected: base + derived

public: base + derived + any other member

varun
A: 

Member in base class   :   Private Protected Public

Inheritance type :             Object inherited as:

Private :                                Private   Private       Private
Protected :                            Private Protected Protected
Public :                                  Private Protected Public