Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should I use C++ private inheritance?

Tags:

c++

oop

People also ask

What is the need of private inheritance in C++?

public, protected and private inheritance in C++ protected inheritance makes the public and protected members of the base class protected in the derived class. private inheritance makes the public and protected members of the base class private in the derived class.

When the inheritance is private the private?

Explanation : Explanation: When the inheritance is private, the private methods in base class are inaccessible in the derived class (in C++). 1.

What type of relationship does private inheritance model?

Private inheritance creates a “is implemented in terms of” relationship between classes, also known as “has-a” relationship. By using composition, you can create the same kind of relationship but with a much looser coupling between the classes.


I use it all the time. A few examples off the top of my head:

  • When I want to expose some but not all of a base class's interface. Public inheritance would be a lie, as Liskov substitutability is broken, whereas composition would mean writing a bunch of forwarding functions.
  • When I want to derive from a concrete class without a virtual destructor. Public inheritance would invite clients to delete through a pointer-to-base, invoking undefined behaviour.

A typical example is deriving privately from an STL container:

class MyVector : private vector<int>
{
public:
    // Using declarations expose the few functions my clients need 
    // without a load of forwarding functions. 
    using vector<int>::push_back;
    // etc...  
};
  • When implementing the Adapter Pattern, inheriting privately from the Adapted class saves having to forward to an enclosed instance.
  • To implement a private interface. This comes up often with the Observer Pattern. Typically my Observer class, MyClass say, subscribes itself with some Subject. Then, only MyClass needs to do the MyClass -> Observer conversion. The rest of the system doesn't need to know about it, so private inheritance is indicated.

Note after answer acceptance: This is NOT a complete answer. Read other answers like here (conceptually) and here (both theoretic and practic) if you are interested in the question. This is just a fancy trick that can be achieved with private inheritance. While it is fancy it is not the answer to the question.

Besides the basic usage of just private inheritance shown in the C++ FAQ (linked in other's comments) you can use a combination of private and virtual inheritance to seal a class (in .NET terminology) or to make a class final (in Java terminology). This is not a common use, but anyway I found it interesting:

class ClassSealer {
private:
   friend class Sealed;
   ClassSealer() {}
};
class Sealed : private virtual ClassSealer
{ 
   // ...
};
class FailsToDerive : public Sealed
{
   // Cannot be instantiated
};

Sealed can be instantiated. It derives from ClassSealer and can call the private constructor directly as it is a friend.

FailsToDerive won't compile as it must call the ClassSealer constructor directly (virtual inheritance requirement), but it cannot as it is private in the Sealed class and in this case FailsToDerive is not a friend of ClassSealer.


EDIT

It was mentioned in the comments that this could not be made generic at the time using CRTP. The C++11 standard removes that limitation by providing a different syntax to befriend template arguments:

template <typename T>
class Seal {
   friend T;          // not: friend class T!!!
   Seal() {}
};
class Sealed : private virtual Seal<Sealed> // ...

Of course this is all moot, since C++11 provides a final contextual keyword for exactly this purpose:

class Sealed final // ...

The canonical usage of private inheritance is the "implemented in terms of" relationship (thanks to Scott Meyers' 'Effective C++' for this wording). In other words, the external interface of the inheriting class has no (visible) relationship to the inherited class, but it uses it internally to implement its functionality.


One useful use of private inheritence is when you have a class that implements an interface, that is then registered with some other object. You make that interface private so that the class itself has to register and only the specific object that its registered with can use those functions.

For example:

class FooInterface
{
public:
    virtual void DoSomething() = 0;
};

class FooUser
{
public:
    bool RegisterFooInterface(FooInterface* aInterface);
};

class FooImplementer : private FooInterface
{
public:
    explicit FooImplementer(FooUser& aUser)
    {
        aUser.RegisterFooInterface(this);
    }
private:
    virtual void DoSomething() { ... }
};

Therefore the FooUser class can call the private methods of FooImplementer through the FooInterface interface, while other external classes cannot. This is a great pattern for handling specific callbacks that are defined as interfaces.


I think the critical section from the C++ FAQ Lite is:

A legitimate, long-term use for private inheritance is when you want to build a class Fred that uses code in a class Wilma, and the code from class Wilma needs to invoke member functions from your new class, Fred. In this case, Fred calls non-virtuals in Wilma, and Wilma calls (usually pure virtuals) in itself, which are overridden by Fred. This would be much harder to do with composition.

If in doubt, you should prefer composition over private inheritance.


I find it useful for interfaces (viz. abstract classes) that I'm inheriting where I don't want other code to touch the interface (only the inheriting class).

[edited in an example]

Take the example linked to above. Saying that

[...] class Wilma needs to invoke member functions from your new class, Fred.

is to say that Wilma is requiring Fred to be able to invoke certain member functions, or, rather it is saying that Wilma is an interface. Hence, as mentioned in the example

private inheritance isn't evil; it's just more expensive to maintain, since it increases the probability that someone will change something that will break your code.

comments on the desired effect of programmers needing to meet our interface requirements, or breaking the code. And, since fredCallsWilma() is protected only friends and derived classes can touch it i.e. an inherited interface (abstract class) that only the inheriting class can touch (and friends).

[edited in another example]

This page briefly discusses private interfaces (from yet another angle).


Sometimes I find it useful to use private inheritance when I want to expose a smaller interface (e.g. a collection) in the interface of another, where the collection implementation requires access to the state of the exposing class, in a similar manner to inner classes in Java.

class BigClass;

struct SomeCollection
{
    iterator begin();
    iterator end();
};

class BigClass : private SomeCollection
{
    friend struct SomeCollection;
    SomeCollection &GetThings() { return *this; }
};

Then if SomeCollection needs to access BigClass, it can static_cast<BigClass *>(this). No need to have an extra data member taking up space.