tags:

views:

4023

answers:

12

Unlike protected inheritance, C++ private inheritance found its way into mainstream C++ development. However, I still haven't found a good use for it.

When do you guys use it?

+20  A: 

See this FAQ.

I find this answer much more helpful than the accepted answer.
Dave Van den Eynde
+1  A: 

I never use it

Tim
Whoa! How many of you -1ers *have* used private inheritance? This post is a valid data point. I'll wager that 90% of C++ programmers never use private inheritance, and never need to.
j_random_hacker
I've only used it for boost::noncopyable. The answer is not helpful though.
Amazing that this is down voted. thanks random_hacker, but some people just need to have an answer - even if it is useless. If you need this kind of construct, i would suggest you are getting a little too tricksy with the classes and the relationships. Oh well.
Tim
I up voted this. The question was "When do you guys use it?" and "I never use it" is a perfectly valid answer.
bias
Not only is it an answer, it's the best answer.
Cameron Pope
If I said "I never used C++ and never needed to", would that be a valid answer?
hasen j
I have not downvoted and I have used private inheritance. Did not downvote as I cannot tell whether your answer is right or wrong, at the end only you know if you have used it or not :)
David Rodríguez - dribeas
There are other uses... blocking copy construction/assignment by inheriting from boost::noncopyable to block the compiler from generating those operators. There is no point in making the inheritance public, it is just an implementation detail, you could just have disabled it yourself.
David Rodríguez - dribeas
+10  A: 

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.

Harper Shelby
May be worth mentioning one of the reasons why it is used in this case: This allows the empty base class optimization to be performed, which won't occur if the class had been a member instead of a base class.
jalf
its main use is to reduce space consumption where it really matters, e.g. in policy controlled string classes or in compressed pairs. actually, boost::compressed_pair used protected inheritance.
Johannes Schaub - litb
jalf: Hey, I didn't realize that. I thought nonpublic inheritance was mainly used as a hack when you need access to a class's protected members. I wonder why an empty object would take up any space when using composition though. Probably for universal addressability...
Michael Burr
i didn't realize this question actually is about private inheritance instead of protected inheritance. yeah i guess there are quite a bit of applications for it. can't think of many examples for protected inheritance though :/ looks like that's only rarely useful.
Johannes Schaub - litb
+1 jalf, litb, Michael Burr.
j_random_hacker
+1  A: 

Sometimes it could be as alternative for aggregation, for example if you want aggregation but with changed behaviour of aggrigable entity (with overriding virtual function).

But you right it have not many explamples from real world.

bb
+4  A: 

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

bias
Doesn't really sound useful... can you post an example
I think I see where you're going... A typical use case might be that Wilma is some type of utility class that needs to call virtual functions in Fred, but other classes need not know that Fred is implemented-in-terms-of Wilma. Right?
j_random_hacker
Yes. I should point out that, to my understanding, the term 'interface' is more commonly used in Java. When I first heard of it I thought it could have been given a better name. Since, in this example we have an interface that no one interfaces with in the way that we normally think of the word.
bias
@Noos: Yes I think your statement "Wilma is an interface" is a bit ambiguous, as most people would take this to mean that Wilma is an interface that Fred intends to supply to *the world*, rather than a contract with Wilma only.
j_random_hacker
@j_ That's why I think interface is a bad name. Interface, the term, needn't mean to *the world* as one would think, but rather is a guarantee of functionality. Actually, I was contentious about the term interface in my Program Design class. But, we use what we are given ...
bias
Addendum: I say interface needn't mean *to the outside world* since an interface includes both *services and attributes* but this is getting philosophical (perhaps lexicological) just like it did in my class.
bias
+8  A: 

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.

Bill the Lizard
+14  A: 

Note after answer acceptance: This is NOT a complete answer. Read other answers like here, here (conceptually) and last but not least 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.

David Rodríguez - dribeas
That's a great technique. I will write an blog entry on it.
Question: if we didn't use virtual inheritance, then FailsToDerive would compile. Correct?
+1. @Sasha: Correct, virtual inheritance is needed since the most-derived class always calls the constructors of all virtually inherited class directly, which is not the case with plain inheritance.
j_random_hacker
This can be made generic, without making a custom ClassSealer for every class you want to seal! Check it out: class ClassSealer { protected: ClassSealer() {} }; that's all.
+1 Iraimbilanja, very cool! BTW I saw your earlier comment (now deleted) about using the CRTP: I think that should in fact work, it's just tricky to get the syntax for template friends right. But in any case your non-template solution is much more awesome :)
j_random_hacker
@Iraimbilanja: If you just make the constructor protected, the most derived object could also derive from ClassSealer (multiple inheritance) and it could call the constructor. That would break the seal. Not checked, though.
David Rodríguez - dribeas
@j_random_hacker: after a couple of tries I failed to get the friendship right, I will try in a couple of days again. But now I am on holidays and will get on the road :)
David Rodríguez - dribeas
j_random_hacker: Well, if you figure out the syntax for template friendship, I'd love to know about it because that would solve the minor loophole dribeas pointed out.
Actually, a bit of research shows that the standard explicitly says it's illegal to declare a template parameter as a friend class in paragraph 7.1.5.3.2. Damn. Why??? (For the record, MSVC++9 accepts "friend T;" and does what you expect.)
j_random_hacker
j_random_hacker :P will be allowed in C++1x .
Johannes Schaub - litb
A: 

Just because C++ has a feature, doesn't mean it's useful or that it should be used.

I'd say you shouldn't use it at all.

If you're using it anyway, well, you're basically violating encapsulation, and lowering cohesion. You're putting data in one class, and adding methods that manipulates the data in another one.

Like other C++ features, it can be used to achieve side effects such as sealing a class (as mentioned in dribeas' answer), but this doesn't make it a good feature.

hasen j
wow... very insightful +1
are you being sarcastic? all I have is a -1! anyway I will not delete this even if it gets -100 votes
hasen j
wonder how hiding details breaks encapsulation...
David Rodríguez - dribeas
wonder no longer, I edited the answer.
hasen j
+18  A: 

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.
fizzer
Wow, this answer is excellent. +1
Krsna
+3  A: 

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.

Daemin
A: 

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.

A: 

In #3, given only the code shown there, what is it about FooUser that would give it access to the private methods of FooImplementer, as is claimed?

sawSiVa