[24] Inheritance — private and protected inheritance
(Part of C++ FAQ Lite, Copyright © 1991-2001, Marshall Cline, cline@parashift.com)


FAQs in section [24]:


[24.1] How do you express "private inheritance"?

When you use : private instead of : public. E.g.,

 class Foo : private Bar {
 public:
   
// ...
 };

TopBottomPrevious sectionNext sectionSearch the FAQ ]


[24.2] How are "private inheritance" and "composition" similar? UPDATED!

[Recently changed the syntax to using Engine::start; and added the sixth distinction thanks to Stan Brown; added the third similarity; added "aggregation" as another synonym; general wordsmithing (in 4/01). Click here to go to the next FAQ in the "chain" of recent changes.]

private inheritance is a syntactic variant of composition (AKA aggregation and/or has-a).

E.g., the "Car has-a Engine" relationship can be expressed using simple composition:

 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
 };

The "Car has-a Engine" relationship can also be expressed using private inheritance:

 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
 };

There are several similarities between these two variants:

There are also several distinctions:

Note that private inheritance is usually used to gain access into the protected members of the base class, but this is usually a short-term solution (translation: a band-aid).

TopBottomPrevious sectionNext sectionSearch the FAQ ]


[24.3] Which should I prefer: composition or private inheritance?

Use composition when you can, private inheritance when you have to.

Normally you don't want to have access to the internals of too many other classes, and private inheritance gives you some of this extra power (and responsibility). But 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.

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.

 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";
     }
 };

TopBottomPrevious sectionNext sectionSearch the FAQ ]


[24.4] Should I pointer-cast from a private derived class to its base class?

Generally, No.

From a member function or friend of a privately derived class, the relationship to the base class is known, and the upward conversion from PrivatelyDer* to Base* (or PrivatelyDer& to Base&) is safe; no cast is needed or recommended.

However users of PrivatelyDer should avoid this unsafe conversion, since it is based on a private decision of PrivatelyDer, and is subject to change without notice.

TopBottomPrevious sectionNext sectionSearch the FAQ ]


[24.5] How is protected inheritance related to private inheritance?

Similarities: both allow overriding virtual functions in the private/protected base class, neither claims the derived is a kind-of its base.

Dissimilarities: protected inheritance allows derived classes of derived classes to know about the inheritance relationship. Thus your grand kids are effectively exposed to your implementation details. This has both benefits (it allows derived classes of the protected derived class to exploit the relationship to the protected base class) and costs (the protected derived class can't change the relationship without potentially breaking further derived classes).

Protected inheritance uses the : protected syntax:

 class Car : protected Engine {
 public:
   
// ...
 };

TopBottomPrevious sectionNext sectionSearch the FAQ ]


[24.6] What are the access rules with private and protected inheritance?

Take these classes as examples:

 class B                    { /*...*/ };
 class D_priv : private   B { 
/*...*/ };
 class D_prot : protected B { 
/*...*/ };
 class D_publ : public    B { 
/*...*/ };
 class UserClass            { B b; 
/*...*/ };

None of the derived classes can access anything that is private in B. In D_priv, the public and protected parts of B are private. In D_prot, the public and protected parts of B are protected. In D_publ, the public parts of B are public and the protected parts of B are protected (D_publ is-a-kind-of-a B). class UserClass can access only the public parts of B, which "seals off" UserClass from B.

To make a public member of B so it is public in D_priv or D_prot, state the name of the member with a B:: prefix. E.g., to make member B::f(int,float) public in D_prot, you would say:

 class D_prot : protected B {
 public:
   using B::f;  
// Note: Not using B::f(int,float)
 };

TopBottomPrevious sectionNext sectionSearch the FAQ ]


E-Mail E-mail the author
C++ FAQ LiteTable of contentsSubject indexAbout the author©Download your own copy ]
Revised Aug 15, 2001