8

Possible Duplicate:
When should I use C++ private inheritance?

I wanted to make this community-wiki but don't see the button... can someone add it?

I can't think of any case I've derived from a class in a non-public way, and I can't recall off-hand seeing code which does this.

I'd like to hear real-world examples and patterns where it is useful.

Community
  • 1
  • 1
Mr. Boy
  • 60,845
  • 93
  • 320
  • 589
  • You cannot make questions CW anymore. If you want, you can flag the mods to do it for you. – sbi Oct 31 '11 at 10:31
  • Also on similar territory to http://stackoverflow.com/questions/2090661/protected-inheritance. Both those questions show that there are cases where people use non-public inheritance, quite defendably (not that I'm saying you were attacking it!). – AAT Oct 31 '11 at 11:08

6 Answers6

6

Your mileage may vary...

The hard-core answer would be that non-public inheritance is useless.

Personally, I use it in either of two cases:

  • I would like to trigger the Empty Base Optimization if possible (usually, in template code with predicates passed as parameters)
  • I would like to override a virtual function in the class

In either cases, I thus use private inheritance because the inheritance itself is an implementation detail.

I have seen people using private inheritance more liberally, and near systematically, instead of composition when writing wrappers or extending behaviors. C++ does not provide an "easy" delegate syntax, so doing so allow you to write using Base::method; to immediately provide the method instead of writing a proper forwarding call (and all its overloads). I would argue it is bad form, although it does save time.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
3

If you chose inheritance for developing a wrapper, private inheritance is the way to go. You no longer need or want access to your base class' methods and members from outside your wrapper class.

class B;
class A
{
public:
   A();
   void foo(B b);
};

class BWrap;
class AWrap : private A
{
public:
   AWrap();
   void foo(BWrap b);
};

//no longer want A::foo to be accessible by mistake here, so make it private
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
3

Since private inheritance has as its only known use implementation inheritance, and since this could always be done using containment instead (which is less simple to use, but better encapsulates the relationship), I'd say it's used too often.

(Since nobody ever told me what protected inheritance means, let's assume nobody knows what it is and pretend it doesn't exist.)

sbi
  • 219,715
  • 46
  • 258
  • 445
  • +1 for the snippet on `protected` inheritance. I sometimes wonder if it was not introduced simply for consistence sake (ie, since `protected` is also an access specifier). – Matthieu M. Oct 31 '11 at 10:44
  • Item 24 in Herb Sutter's "Exceptional C++" provides the only example I've ever seen of protected inheritance. – Gorpik Oct 31 '11 at 10:47
  • @Matthieu: I think `protected` inheritance wasn't really _introduced_ into the language. Rather than that, nobody bothered _removing_ it. `:)` – sbi Oct 31 '11 at 10:49
  • @Gorpik: Oh, I have that book at home and forgot this example. Care to elaborate? – sbi Oct 31 '11 at 10:49
  • 1
    @MatthieuM.: That's almost surely the case. It'd be inconsistent not to have it, and it doesn't get in the way; but the C++ philosophy is to give you complete control over your code, and that comes with some aspects that you never actually asked for. I'm sure there are other examples... – Kerrek SB Oct 31 '11 at 10:52
  • @sbi: It deals with modelling a kind of internal polymorphic behaviour (i.e. the class behaves polymorphically internally, but not externally) that can be inherited. – Gorpik Oct 31 '11 at 14:07
  • @Gorpik: That doesn't ring a bell, so I will have to look it up when I'm back at home. Thanks! – sbi Oct 31 '11 at 14:38
2

Sometimes inheriting the classes which are neither having any virtual functions nor a virtual destructor (e.g. STL containers), you may have to go for non-public inheritance. e.g.

template<typename T>
struct MyVector : private std::vector<T>
{ ... };

This will disallow, handles (pointer or reference) of base (vector<>) to get hold of derived class (MyVector<>):

vector<int> *p = new MyVector<int>; // compiler error
...
delete p;  // undefined behavior: ~vector() is not 'virtual'!

Since, we get compiler error at the first line itself, we will be saved from the undefined behavior in the subsequent line.

iammilind
  • 68,093
  • 33
  • 169
  • 336
  • But why would you use private inheritance instead of composition here ;) ? – Matthieu M. Oct 31 '11 at 10:32
  • @MatthieuM., though it's a matter of taste, but composition will not allow the operations like `is_base_of<>`. :) – iammilind Oct 31 '11 at 10:35
  • I know there have been some changes on access rules in SFINAE contexts in C++11... I don't think that `is_base_of` allows `public` access to the knowledge that the base class is used, and `private` clients can always query the member itself... so what's the use ? – Matthieu M. Oct 31 '11 at 10:47
  • What would be the use of *knowing* that your type derives from another type if that inheritance relationship is blocked from you (i.e. you cannot make use of it)? I am with Matthieu, this is a rather poor reason to use private inheritance. (BTW, `is_base_of` in g++4.6 does return `true` in the case of private inheritance.... go figure) – David Rodríguez - dribeas Oct 31 '11 at 10:54
2

If you are deriving from a class without a virtual destructor then Public inheritance leads to a chance that users of the class can call delete on a pointer-to-base, which leads to undefined behaviour.
In such an scenario it makes sense to use private Inheritance.

Most common example of this is to derive privately from STL containers which do not have virtual destructors.


C++FAQ has an excellent example of Private Inheritance which extends to many real live scenarios.

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.

Code Example:

class Wilma {
 protected:
   void fredCallsWilma()
     {
       std::cout << "Wilma::fredCallsWilma()\n";
       wilmaCallsFred();
     }
   virtual void wilmaCallsFred() = 0;   // A pure virtual function
 };

 class Fred : private Wilma {
 public:
   void barney()
     {
       std::cout << "Fred::barney()\n";
       Wilma::fredCallsWilma();
     }
 protected:
   virtual void wilmaCallsFred()
     {
       std::cout << "Fred::wilmaCallsFred()\n";
     }
 }; 
Alok Save
  • 202,538
  • 53
  • 430
  • 533
1

Non-public (almost always private) inheritance is used when inheriting (only) behavior, and not interface. I've used it mostly, but not exclusively, in mixins.

For a good discussion on the topic, you might want to read Barton and Nackman (Scientific and Engineering C++: An Introduction with Advanced Techniques and Examples, ISBN 0-201-53393-6. Despite the name, large parts of the book are applicable to all C++, not just scientific and engineering applications. And despite its date, it's still worth reading.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329