9

I dont completely understand this:

class Base
{
    public:
    Base()
    {
        cout<<"Base" << endl;
    }

    virtual void call()
    {
        cout<<"Base call" << endl; 
    }
};

class Derived: private Base
{
    public:      
    Derived()
    {
        cout<<"Derived" << endl;
    } 
};

int main(void)
{
    Base *bPtr = new Derived(); // This is not allowed
}

Is it because someone might call call() using bPtr which is actually done on derived object? Or is there any other reason?

laalto
  • 150,114
  • 66
  • 286
  • 303
nitin soman
  • 145
  • 2
  • 4

6 Answers6

26

Public inheritance means that everyone knows that Derived is derived from Base.

Protected inheritance means that only Derived, friends of Derived, and classes derived from Derived know that Derived is derived from Base.*

Private inheritance means that only Derived and friends of Derived know that Derived is derived from Base.

Since you have used private inheritance, your main() function has no clue about the derivation from base, hence can't assign the pointer.

Private inheritance is usually used to fulfill the "is-implemented-in-terms-of" relationship. One example might be that Base exposes a virtual function that you need to override -- and thus must be inherited from -- but you don't want clients to know that you have that inheritance relationship.

*also: how much wood would a woodchuck chuck...

Kaz Dragon
  • 6,681
  • 2
  • 36
  • 45
  • 7
    Three and a half years later, and an addendum to my answer: in the case of private inheritance, note that not even Base knows that Derived is derived from Base. That is, `dynamic_cast(this)` in a member function of Base will always return NULL if Derived privately inherits from Base. I mention this because it bit me recently when attempting private inheritance of a class passed in via the Curiously Recursive Template Pattern. – Kaz Dragon May 29 '13 at 14:23
  • I'd like to also add that `dynamic_cast(base_ptr)` doesn't work *even in `Derived`* https://godbolt.org/z/ajxqe6GzY – apple apple Apr 18 '23 at 14:55
  • related: https://stackoverflow.com/q/12765174/5980430, https://stackoverflow.com/a/62448359/5980430 – apple apple Apr 18 '23 at 18:07
23

From a common understanding of inheritance, C++’ “private inheritance” is a horrible misnomer: it is not inheritance (as far as everything outside of the class is concerned) but a complete implementation detail of the class.

Seen from the outside, private inheritance is actually pretty much the same as composition. Only on the inside of the class do you get special syntax that is more reminiscent of inheritance than composition.

There’s a caveat though: C++ syntactically treats this as inheritance, with all the benefits and problems that this entails, such as scope visibility and accessibility. Furthermore, C-style casts (but no C++ cast!) actually ignores visibility and thus succeeds in casting your Derived pointer to Base:

Base* bPtr = (Base*) new Derived();

Needless to say, this is evil.

Community
  • 1
  • 1
Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • 8
    It's implementation inheritance rather than interface inheritance. – Laurence Gonsalves Oct 16 '09 at 09:30
  • @Laurence: true, but that’s just arguing terminology. I was concerned with the outside view on the class. – Konrad Rudolph Oct 16 '09 at 10:21
  • 1
    "_it is not inheritance_" Absolutely wrong. It **is** inheritance, with private access. – curiousguy Dec 26 '11 at 00:03
  • 2
    @curiousguy (I’m not sure why I even bother) see my answer to Laurence’s comment. Also, I’m aware that it’s a simplification (C-style casts even outside the class are able to cast in private-inheritance hierarchies). But it’s a useful (*the* most useful, in my opinion) intuition about private inheritance. – Konrad Rudolph Dec 26 '11 at 10:59
  • @KonradRudolph "_C-style casts even outside the class are able to cast in private-inheritance hierarchies_" That wasn't my concern at all. Anyone who uses a cast is expected to know what he is doing, and to take full responsibility. And someone using a C cast instead of distinguished cast is even _more_ expected to know what he is doing. (Someone who really wants to get around the type system, or access control, is probably going to do it no matter what - even if it means doing very dirty things.) – curiousguy Feb 18 '12 at 05:44
  • "_it is not inheritance_" People will be surprised if they understand that it really is inheritance, like [Inaccessible type due to private inheritance](http://stackoverflow.com/questions/8011090/inaccessible-type-due-to-private-inheritance) – curiousguy Feb 18 '12 at 05:46
  • Speaking of c-style casts: Suppose Derived uses multiple private inheritance ("class Derived: private Base1, private Base 2"). And then they write "Base2 *bPtr = (Base2*)new Derived;". Does the right thing happen? (That is, is the raw pointer value adjusted so it points to the Base2 part of Derived?) – jorgbrown Jan 23 '15 at 22:57
12

Because private means "implementation detail", which makes the fact that Derived derives from Base an implementation detail.

Private inheritance is not interface inheritance, but implementation inheritance. It doesn't implement an "Is-A" relationship, but an "Is-Implemented-Using" relationship. Derived isn't a Base as far as users of the classes are concerned, it just happens to (currently) be implemented using it.

sbi
  • 219,715
  • 46
  • 258
  • 445
1

With private inheritance, you lose the option to treat your derived object as an object of your base class.

xpda
  • 15,585
  • 8
  • 51
  • 82
Maximilian Mayerl
  • 11,253
  • 2
  • 33
  • 40
1

If you inherit privately any code that requires the conversion from Derived* to Base* must be a member or a friend of the Derived class.

sellibitze
  • 27,611
  • 3
  • 75
  • 95