When Should I Use C++ Private Inheritance

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 that Base contains publicMember.
  • Only the children (and their children) are aware that Base contains protectedMember.
  • No one but Base is aware of privateMember.

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 of Base and Child is also aware that Child inherits from Base.
  • If the inheritance is protected, only Child, and its children, are aware that they inherit from Base.
  • If the inheritance is private, no one other than Child 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 call foobar with *this, a conversion is necessary; specifically, *this of type Bar needs to be converted to Foo&, which is possible since the caller is aware of the inheritance relation between the two types.
  • In main(), outside class Bar scope then, the call to foobar with b which is of type Bar also needs a conversion. But in this context, the relation between Bar and Foo 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



Leave a reply



Submit