Private Inheritance VS Composition:When to Use Which

When to use C++ private inheritance over composition?

private inheritance is typically used to represent "implemented-in-terms-of". The main use I have seen is for mixins using private multiple inheritance to build up a child object with the proper functionality from the various mixin parents. This can also be done with composition (which I slightly prefer) but the inheritance method DOES allow you to use using to expose some parent methods publicly, and allows for a slightly more convenient notation when using the mixin methods.

Private inheritance and composition, which one is best and why?

I prefer to think of inheritance as derived is a kind of base, that basically means public inheritance. In case of private inheritance it more like derived has a base, which IMHO doesn't sound right, because that's IMHO the work for composition not inheritance of any kind. So, since private inheritance and composition essentially mean same thing logically, which to choose? With the example you posted, I'd most certainly go for composition. Why? I tend to think of all kinds of inheritance as a kind of relationship, and with the example you posted, I can't think of a situation where I could say a car is kind of an engine, it simply isn't. It's indeed like a car has an engine, so why would a car inherit from an engine? I see no reason.

Now, indeed there are cases where it's good to have private inheritance, namely boost::noncopyable, with it's ctor/dtor being protected, you'd have hard time instantiating it, and indeed since we want our class to have a noncopyable part, that's the only way to go.

Some style guides (e.g. google c++ style guide) even recommend to never use private inheritance, for reasons similar to what I already written - private inheritance is just a bit confusing.

When should I use C++ private inheritance?

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 // ...

Difference between Inheritance and Composition

They are absolutely different. Inheritance is an "is-a" relationship. Composition is a "has-a".

You do composition by having an instance of another class C as a field of your class, instead of extending C. A good example where composition would've been a lot better than inheritance is java.util.Stack, which currently extends java.util.Vector. This is now considered a blunder. A stack "is-NOT-a" vector; you should not be allowed to insert and remove elements arbitrarily. It should've been composition instead.

Unfortunately it's too late to rectify this design mistake, since changing the inheritance hierarchy now would break compatibility with existing code. Had Stack used composition instead of inheritance, it can always be modified to use another data structure without violating the API.

I highly recommend Josh Bloch's book Effective Java 2nd Edition

  • Item 16: Favor composition over inheritance
  • Item 17: Design and document for inheritance or else prohibit it

Good object-oriented design is not about liberally extending existing classes. Your first instinct should be to compose instead.


See also:

  • Composition versus Inheritance: A Comparative Look at Two Fundamental Ways to Relate Classes

Does private inheritance always mean HAS-A?

You example can be implemented through composition like this:

class A {
private:
class B {
B(const B&) = delete;
B& operator=(const B&) = delete;
} b;
};

A is noncopyable, because its member b is noncopyable.

Composition over private inheritance

All the time. The real question is, when is private inheritance preferred over composition? Only when virtual functions are required. Else, always favour composition.



Related Topics



Leave a reply



Submit