C++ standard supports three types of inheritance: public, protected and private. One of the main differences is the accessibility of the public and protected members – their accessibility is narrowed to the type of inheritance. Private members are always not accessible from derived class. The code below presents the members scope depending on the inheritance type.

class B : public A
{
    // public member of A is public
    // protected member of A is protected
    // private member of A is not accessible from B
};

The public and protected members’ scope doesn’t change when the inheritance is public. Private members can’t be accessed from derived class.

class C : protected A
{
    // public member of A is protected
    // protected member of A is protected
    // private member of A is not accessible from C
};

For protected inheritance, the public members become protected and protected members stay protected. This type of inheritance is rarely useful.

class D : private A
{
    // public member of A is private
    // protected member of A is private
    // private member of A  is not accessible from D
};

Both public and protected members are private in derived class.

Public inheritance

Usage of public inheritance is pretty common and means is-a relationship. The derived class can be always used when the base class is needed. In the example below, the DerivedPublic class object is passed to the function which awaits Base class and everything is fine.

class Base {};

class DerivedPublic: public Base {};

void doSmthOnBase(const Base& base){}

DerivedPublic d;
doSmthOnBase(d); // great!

Private inheritance

Would you be able to do the same trick when the derived class inherits privately from Base? Unfortunately not. Such piece of code will not compile:

class Base {};

class DerivedPrivate: private Base {};

void doSmthOnBase(const Base& base){}

DerivedPrivate d;
doSmthOnBase(d); // error !

The compiler will complain about error: ‘Base’ is an inaccessible base of ‘Derived’ doSmthOnBase(d). That means that, unlike public inheritance, private inheritance is not an “is-a” relationship.

So what’s the use of private inheritance?

Private inheritance means “has-a” relationship (or: “is implemented in terms of”). Similar to composition, you should use private inheritance when you want to make use of the implementation details of base class, but you do not want to inherit the interface.

When private inheritance is better than composition?

You will have to use private inheritance when you need to have access to protected members/member functions of base class. In other cases almost always you should use composition. Private inheritance will make your code harder to maintain and increase the compilation dependencies (in case of composition, you can use forward declaration and a member-pointer to object).

Empty Base Optimization (EBO)

There is one more specific case when private inheritance can be reasonable: so called Empty Base Optimization. Imagine EmptyClass with zero non-static members and zero virtual functions nor base classes. Composition of EmptyClas will increase the size of OtherClass_composition.

class EmptyClass{};
class OtherClass_composition 
{ 
    private: 
        EmptyClass m_empty; 
        int m_member;
};

But if you use private inheritance you will save some space.

class OtherClass_inheritance : private EmptyClass
{   
    private: 
        int m_member;
};

In this case, the size of OtherClass_inheritance should not increase (but it’s dependant on the compiler). With the use of MinGW 4.9.1 the size of OtherClass_composition was 8, while the size of OtherClass_inheritance was 4.

Further readings: