70

In C++, I can't think of a case in which I would like to inherit private/protected from a base class:

class Base;
class Derived1 : private Base;
class Derived2 : protected Base;

Is it really useful?

user366312
  • 16,949
  • 65
  • 235
  • 452
Gal Goldman
  • 8,641
  • 11
  • 45
  • 45
  • 4
    Consider this: a circle is an ellipse but [Circle is not substitutable for Ellipse](http://stackoverflow.com/questions/7602102/teach-dynamic-polymorphism-with-simple-example/7677015#7677015), public inheritance is ***not*** an is-a relationship, although we often call it so. – spraff Jan 04 '12 at 11:43
  • 7
    Circle is indeed an ellipse. Not sure what you mean? – user4951 Nov 28 '13 at 09:21

8 Answers8

60

It is useful when you want to have access to some members of the base class, but without exposing them in your class interface. Private inheritance can also be seen as some kind of composition: the C++ faq-lite gives the following example to illustrate this statement

class Engine {
 public:
   Engine(int numCylinders);
   void start();                 // Starts this Engine
};

class Car {
  public:
    Car() : e_(8) { }             // Initializes this Car with 8 cylinders
    void start() { e_.start(); }  // Start this Car by starting its Engine
  private:
    Engine e_;                    // Car has-a Engine
};

To obtain the same semantic, you could also write the car Class as follow:

class Car : private Engine {    // Car has-a Engine
 public:
   Car() : Engine(8) { }         // Initializes this Car with 8 cylinders
   using Engine::start;          // Start this Car by starting its Engine
}; 

However, this way of doing has several disadvantages:

  • your intent is much less clear
  • it can lead to abusive multiple inheritance
  • it breaks the encapsulation of the Engine class since you can access its protected members
  • you're allowed to override Engine virtual methods, which is something you don't want if your aim is a simple composition
Luc Touraille
  • 79,925
  • 15
  • 92
  • 137
  • 24
    In my opinion, in case of "has a" there shouldn't be any inheritance, but there should a composition. I think this is a bad example of abusing inheritance, because it confuses the users. – Gal Goldman Dec 18 '08 at 08:11
  • 9
    The second example is a very bad example other wise you would end up like this: class Car : private Engine, private Wheel, private Seat – Lodle Dec 18 '08 at 08:45
  • 3
    Yes "has-a" should not be inheritance. I use private inheritance for "is-implemented-in-temrs-of". which actually means "is-a" but as a sort of hack. Like you reused a piece of code that wasn't really supposed to give these sorts of offspring, but hey... – v.oddou Jul 15 '15 at 01:52
42

Private can be useful in quite a few circumstances. Just one of them are policies:

Is partial class template specialization the answer to this design problem?.

Another occasion where it is useful is to forbid copying and assigning:

struct noncopyable {
    private:
    noncopyable(noncopyable const&);
    noncopyable & operator=(noncopyable const&);
};

class my_noncopyable_type : noncopyable {
    // ...
};

Because we don't want that the user has a pointer of type noncopyable* to our object, we derive privately. That counts not only for noncopyable, but many other such classes too (policies being the most common).

Community
  • 1
  • 1
Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • 1
    It really doesn't matter if you derive noncopyable publicly or privately, since the copy constructor and assignment operator are private anyway. – Marcin Dec 18 '08 at 14:53
  • 7
    As @litb states in his answer, deriving privately prevents the user from referencing an instance of my_non_copyable_type with a pointer or a reference to a noncopyable. – Luc Touraille Dec 18 '08 at 15:26
  • 2
    yes, and that also prevents users to delete through a pointer to that noncopyable. – Johannes Schaub - litb Dec 19 '08 at 12:30
  • if we want to prevent interfaces or members exploring to third callers. should we simply make base class members and functions protected? – Korben Mar 01 '16 at 12:47
16

Public inheritance models IS-A.
Non-public inheritance models IS-IMPLEMENTED-IN-TERMS-OF.
Containment models HAS-A, which is equivalent to IS-IMPLEMENTED-IN-TERMS-OF.

Sutter on the topic. He explains when you'd choose non-public inheritance over containment for implementation details.

Greg Rogers
  • 35,641
  • 17
  • 67
  • 94
3

For instance, when you want to reuse the implementation, but not the interface of a class AND override its virtual functions.

Nemanja Trifunovic
  • 24,346
  • 3
  • 50
  • 88
3

Private inheritance is mostly used for wrong reason. People use it to IS-IMPLEMENTED-IN-TERMS-OF, as indicated in an earlier answer, but in my experience it's always more clean to keep a copy rather than inherit from class. Another earlier answer, the one about CBigArray, provides a perfect example of this anti-pattern.

I realize that there may be cases when has-a does not work due to over-zealous use of "protected", but it's better to fix the broken class than to break a new class.

  • That's a viable choice in many cases. But if you ever end up with a "dreaded diamond of death", then the compiler won't help you (with virtual inheritance), you'll have to fix the problem yourself. – curiousguy Aug 17 '12 at 20:05
1

I've used both private and protected inheritence at one point or other.

Private inheritence is useful when you want something to have the behaviour of the base class, and then be able to override that functionality, but you don't want the whole world to be aware of it and use it. You can still use the interface of a privately derived class by having a function return that interface. It's also useful when you can have things register themselves to listen for callbacks as they can register themselves using the private interface.

Protected inheritence is especially useful when you have a base class that derives useful functionality from another class but you only want its derived classes to be able to use it.

Dominik Grabiec
  • 10,315
  • 5
  • 39
  • 45
0

Private inheritance is most likely to be a legitimate design strategy when you’re dealing with two classes not related by is-a where one either needs access to the protected members of another or needs to redefine one or more of its virtual functions.

From Scott Meyers Effective C++ 3rd Edition page in 191.

HenryTien
  • 105
  • 1
  • 2
-1

I once implemented these data structures as classes:

  • Linked list
  • Generic array (abstract)
  • Simple array (inherits from generic array)
  • Big array (inherits from generic array)

The big array's interface would make it look like an array, however, it was actually a linked list of fixed-size simple arrays. So I declared it like this:

template <typename T>
class CBigArray : public IArray, private CLnkList {
    // ...
isekaijin
  • 19,076
  • 18
  • 85
  • 153