When should I use C++ private inheritance?
Note after answer acceptance: This is NOT a complete answer. Read other answers like here (conceptually) and 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.
EDIT
It was mentioned in the comments that this could not be made generic at the time using CRTP. The C++11 standard removes that limitation by providing a different syntax to befriend template arguments:
template <typename T>
class Seal {
friend T; // not: friend class T!!!
Seal() {}
};
class Sealed : private virtual Seal<Sealed> // ...
Of course this is all moot, since C++11 provides a final
contextual keyword for exactly this purpose:
class Sealed final // ...
When to use C++ private inheritance over composition?
private
inheritance is typically used to represent "implemented-in-terms-of". The main use I have seen is for mixins using private multiple inheritance to build up a child object with the proper functionality from the various mixin parents. This can also be done with composition (which I slightly prefer) but the inheritance method DOES allow you to use using
to expose some parent methods publicly, and allows for a slightly more convenient notation when using the mixin methods.
Why do we actually need Private or Protected inheritance in C++?
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
What is the difference between public, private, and protected inheritance in C++?
To answer that question, I'd like to describe member's accessors first in my own words. If you already know this, skip to the heading "next:".
There are three accessors that I'm aware of: public
, protected
and private
.
Let:
class Base {
public:
int publicMember;
protected:
int protectedMember;
private:
int privateMember;
};
- Everything that is aware of
Base
is also aware thatBase
containspublicMember
. - Only the children (and their children) are aware that
Base
containsprotectedMember
. - No one but
Base
is aware ofprivateMember
.
By "is aware of", I mean "acknowledge the existence of, and thus be able to access".
next:
The same happens with public, private and protected inheritance. Let's consider a class Base
and a class Child
that inherits from Base
.
- If the inheritance is
public
, everything that is aware ofBase
andChild
is also aware thatChild
inherits fromBase
. - If the inheritance is
protected
, onlyChild
, and its children, are aware that they inherit fromBase
. - If the inheritance is
private
, no one other thanChild
is aware of the inheritance.
With private inheritance, when is it ok to upcast?
It all comes from the fact that foobar
receives a Foo
and is ignorant of the fact that Bar
(privatly) inherits from Foo
. This trait is taken care of by the callers:
- Inside
Bar
's constructor, in order to callfoobar
with*this
, a conversion is necessary; specifically,*this
of typeBar
needs to be converted toFoo&
, which is possible since the caller is aware of the inheritance relation between the two types. - In
main()
, outsideclass Bar
scope then, the call tofoobar
withb
which is of typeBar
also needs a conversion. But in this context, the relation betweenBar
andFoo
is unknown, and there is no conversion possible.
Private inheritance means only the derived type knows of this inheritance. In its scope, everything happens as if it was a public inheritance. But outside the scope of the derived type, this relation is unknown and everything happens as if there was no inheritance at all.
C++ why use public, private or protected inheritance?
Use public inheritance to reflect an is-a relationship. This is the main use for inheritance, especially in combination with virtual functions. It allows re-use of interface, not just of old code by new code, but also re-use of new code by old code! (because of virtual function dispatch at runtime).
In exceptional circumstances, use private inheritance to reflect an is-implemented-in-terms-of relationship. This is a commonly overused pattern, often the equivalent goal can be reached through composition (having the would-be base class as a data member). Another drawback is that you can easily have multiple inheritance of the same base class (twice or more removed) leading to the so-called Diamond Problem.
Avoid using protected inheritance, it suggest that your class interface is client-dependent (derived classes versus the world). Often this is due to classes having multiple responsiblities, suggesting a refactoring into separate classes is appropriate.
private inheritance
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.
How to use Private Inheritance aka C++ in C# and Why not it is present in C#
Now, Is there a way to create a HAS-A relationship between C# classes which is one of the thing that I would like to know - HOW?
Make one class have a field of the other class:
class Car
{
Engine engine;
}
A car has an engine.
Another curious question is why doesn't C# support the private (and also protected) inheritance ?
You have a box in your basement. You have never once put anything into it. Someone asks you "why is this box empty?" What answer can you possibly give other than that the box is empty because no one ever put anything into it?
C# doesn't support private or protected inheritance because no one ever implemented that feature and shipped it to customers. Features are not implemented by default, for free. It's not like we started C# with private and protected inheritance and then took them out for some good reason. Those features were never there in the first place, and unsurprisingly, they are still not there. Features don't grow themselves.
Is not supporting multiple implementation inheritance a valid reason or any other?
I don't understand the question.
Is private (and protected) inheritance planned for future versions of C#?
No.
Will supporting the private (and protected) inheritance in C# make it a better language than it is now?
I don't think so.
One of the many problems with inheritance as we typically see it in OOP is that it utterly conflates the "is a kind of" semantic relationship with the "reuses implementation details of" mechanism relationship. Private inheritance partially addresses this problem.
There are a small number of situations in which I would have really liked to have private inheritance in C#; a recent example was that I had a data structure which was possible to construct generally, but which I did not want to expose to users:
internal class FancyDataStructure<T> {...}
but only possible to serialize when T was int (for reasons which are not germane to the discussion.) I would have liked to say:
public class SerializableThingy : private FancyDataStructure<int>
Instead I just made FancyDataStructure<T>
a nested type of SerializableThingy
and used composition rather than inheritance. There was a small amount of "plumbing" code to write but it worked out just fine.
I don't think adding the feature pays for itself; it adds complexity to the language in exchange for a very small benefit of avoiding some trivial plumbing taxes.
Would supporting the private (and protected) inheritance in C# make it a more widely used language than it is now?
How could I, or anyone else for that matter, possibly know the answer to that question? StackOverflow is a bad place to ask questions that require a prediction of the future based on a counterfactual. My suggestions:
- Implement a version of C# with the feature you want. See if it becomes popular. Then you'll know.
- Find someone with psychic powers who can predict how the future would be if things were different now. Since predictions based on counterfactuals are automatically true by the rules of deductive logic, the predictions will be accurate.
Related Topics
Efficiently Load a Large Mat into Memory in Opencv
Accessing Inherited Variable from Templated Parent Class
Examples of When a Bitwise Swap() Is a Bad Idea
Why Does C++ Compilation Take So Long
How to Efficiently Select a Standard Library Container in C++11
Random Number Generation in C++11: How to Generate, How Does It Work
How to Link Opencv in Qtcreator and Use Qt Library
Why Is Conversion from String Constant to 'Char*' Valid in C But Invalid in C++
Correct Way of Declaring Pointer Variables in C/C++
How to Hide a String in Binary Code
Implementing Comparison Operators Via 'Tuple' and 'Tie', a Good Idea
Is There Any Use For Unique_Ptr With Array
Why Is Address Zero Used For the Null Pointer
When Are Static C++ Class Members Initialized
Best Way to Extract a Subvector from a Vector