Private inheritance and composition, which one is best and why? [closed] - c++

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
suppose i have a class engin and i inherit a class car from engin class
class engin
{
public:
engin(int nobofcylinders);
void start();
};
class car:private engin
{
public:
car():e(8){}
void start()
{
e.start();
}
private:
engin e;
};
now the same can be done by the composition, the question is which approch would be best and is mostly used in programming, and why???????

Composition is to be preferred for two main reasons:
the thing(s) being composed can have names
you can compose more than one thing of the same type

I prefer to think of inheritance as derived is a kind of base, that basically means public inheritance. In case of private inheritance it more like derived has a base, which IMHO doesn't sound right, because that's IMHO the work for composition not inheritance of any kind. So, since private inheritance and composition essentially mean same thing logically, which to choose? With the example you posted, I'd most certainly go for composition. Why? I tend to think of all kinds of inheritance as a kind of relationship, and with the example you posted, I can't think of a situation where I could say a car is kind of an engine, it simply isn't. It's indeed like a car has an engine, so why would a car inherit from an engine? I see no reason.
Now, indeed there are cases where it's good to have private inheritance, namely boost::noncopyable, with it's ctor/dtor being protected, you'd have hard time instantiating it, and indeed since we want our class to have a noncopyable part, that's the only way to go.
Some style guides (e.g. google c++ style guide) even recommend to never use private inheritance, for reasons similar to what I already written - private inheritance is just a bit confusing.

If you want to compare private inheritance with composition, read http://www.parashift.com/c++-faq-lite/private-inheritance.html#faq-24.3. I don't think private inheritance is good.
A Car has-an Engine, but a Car is-not-an Engine, so it should be better done with composition.
Inheritence is useful for "is-a" relationships, e.g. a Bus is-a Car, a Car is-a vehicle, etc.
Composition is useful for "has-a" relationships, e.g. a Car has Wheel-s, a Car has-an Engine, etc.
So a logical code should be like
class Car : public Vehicle {
Engine engine;
Wheel wheels[4];
...
};

Private inheritance, despite the name, isn’t really inheritance – at least not from the outside (of the class), where it matters.
For that reason, different rules apply. In C++, private inheritance is said to model an “is implemented in terms of” relationship. Thus, a priority queue which is implemented in terms of a heap, could look like this:
template <typename T, typename Comp = std::less<T> >
class priority_queue : private heap<T, Comp> {
// …
};
Personally, I don’t see the advantage of this pattern, and Neil has already stated that in most cases, composition actually has the advantage over private inheritance.
One advantage exists, though: since it’s such an established pattern, the meaning of a private inheritance is immediately clear to a seasoned C++ programmer; the above code would tell them that the priority queue is implemented in terms of a heap – which wouldn’t be obvious if the class just happened to use a heap as one of its members.
Private inheritance tends to get used in C++ primarily for policy classes. The classical example is allocators, which determine how a container class manages storage internally:
template <typename T, typename A = std::allocator<T> >
class vector : private A {
// …
};
No harm done. But once again, this could also have been done using composition.

Usually, composition is to be preferred (others gave the major reasons), but private inheritance allows things which can't be done by composition:
zero-size base class optimization (a base class of size zero will not increase the size of a class, a member of size zero will), that't the reason behind its use for policy classes which often have no data members
controlling initialization order so that what is composed is initialized before a public base
overriding a virtual member in what is composed
with private virtual inheritance, ensuring that there is only one composed thing even if one do it in several bases
Note that for the later two uses, the fact that the base class exist can be observed in a descendant.

Composition is used more than private inheritance. The general rule I follow and would recommend is that unless you have a specific reason to use private inheritance you should use composition.
Composition has many benefits over private inheritance:
You can have more than one instance of a particular class.
You don't pollute your class' namespace with a bunch of private functions that don't make sense for your class.
You can give names to the parts of your object
Your class is less coupled to the classes it's composed of than it is to a class it inherits from
If you discover you need to swap out an object that you've included by composition during the lifetime of your object, you can, with private inheritance you're stuck.
There are a lot of other benefits to composition. Basically, it's more flexible and cleaner.
There are reasons to use private inheritance though. They are very specific reasons, and if you think they apply, you should think carefully about your design to make sure you have to do it that way.
You can override virtual functions.
You can get access to protected members of the base class.
You need to pass yourself to something that wants an object of the class you're inheriting from (this usually goes hand-in-hand with overriding virtual functions).
And there are a few rather tricky ones as well:
If you use composition for a class that has 0 size, it still takes up space, but with private inheritance it doesn't.
You want to call a particular constructor for a virtual base class of the class you're going to privately inherit from.
If you want to initialize the private base before other base classes are initialized (with composition, all the variables in your class will be initialized after all your base classes are).
Using private virtual inheritance to make sure there's only one copy of a thing even when you have multiple base classes that have it. (In my opinion, this is better solved using pointers and normal composition.)

Private inheritance means
is-implemented-in-terms of. It's
usually inferior to composition, but
it makes sense when a derived class
needs access to protected base class
members or needs to redefine
inherited virtual functions.
Unlike composition, private
inheritance can enable the empty base
optimization. This can be important
for library developers who strive to
minimize object sizes.
Scott Meyers "Effective C++" Third Edition.

Base classes are evil.
In my mind, good OO design is about encapsulation and interfaces. The convenience of base classes are not worth the price you pay.
Here's a really good article about this:
http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html

Related

Example for non-virtual multiple inheritance

Is there a real-world example where non-virtual multiple inheritance is being used? I'd like to have one mostly for didactic reasons. Slapping around classes named A, B, C, and D, where B and C inherit from A and D inherits from B and C is perfectly fine for explaining the question "Does/Should a D object have one or two A sub-objects?", but bears no weight about why we even have both options. Many examples care about why we do want virtual inheritance, but why would we not want virtual inheritance?
I know what virtual base classes are and how to express that stuff in code. I know about diamond inheritance and examples of multiple inheritance with a virtual base class are abundant.
The best I could find is vehicles. The base class is Vehicle which is inherited by Car and Boat. Among other things, a Vehicle has occupants() and a max_speed(). So an Amphibian that inherits from both Car and Boat inherits different max_speed() on land and water – and that makes sense –, but also different occupants() – and that does not make sense. So the Vehicle sub-objects aren't really independent; that is another problem which might be interesting to solve, but this is not the question.
Is there an example, that makes sense as a real-world model, where the two sub-objects are really independent?
You're thinking like an OOP programmer, trying to design abstract models of things. C++ multiple inheritance, like many things in C++, is a tool that has a particular effect. Whether it maps onto some OOP model is irrelevant next to the utility of the tool itself. To put it another way, you don't need a "real-world model" to justify non-virtual inheritance; you just need a real-world use case.
Because a derived class inherits the members of a base class, inheritance often is used in C++ as a means of collecting a set of common functionality together, sometimes with minimal interaction from the derived class, and injecting this functionality directly into the derived class.
The Curiously Recurring Template Pattern and other mixin-like constructs are mechanisms for doing this. The idea is that you have a base class that is a template, and its template parameter is the derived class that uses it. This allows the base class to have some access to the derived class itself without virtual functions.
The simplest example I can think of in C++ is enable_shared_from_this, which allows an object whose lifetime is currently managed by a shared_ptr to actually retrieve a shared_ptr to that object just from a pointer/reference to that object. That uses CRTP to add the various members and interfaces needed to make shared_from_this possible to the derived class. And since the inheritance is public, it also allows shared_ptr's various functions that "enable shared_from_this" to to detect that a particular type has the shared_from_this stuff in it and to properly initialize it.
enable_shared_from_this doesn't need virtual inheritance, and indeed would probably not work very well with it.
Now imagine that I have some other CRTP class that injects some other functionality into an object. This functionality has nothing to do with shared_ptr, but it uses CRTP and inheritance.
Well, if I now write some type that wants to inherit from both enable_shared_from_this and this other functionality, well, that works just fine. There is no need for virtual inheritance, and in fact doing so would only make composition that much harder.
Virtual inheritance is not free. It fundamentally changes a bunch of things about how a type relates to its base classes. If you inherit from such a type, your constructors have to initialize any virtual base classes directly. The layout of such a type is very odd and is highly unlikely to be standardized. And various other things. C++ tries not to make programmers pay for functionality they don't use, so if you don't need the special properties of virtual inheritance, you shouldn't be using it.
Its the same reason C++ has non-virtual methods -- because the implementation is simpler and more efficient if you use non-virtual inheritance, so you need to explicitly ask for virtual inheritance if you want it. Since you don't need it if your classes never use multiple inheritance, that is the default.

Does multi-layer inheritance make sense in C++?

I use 3-layer inheritance design below:
class connect_info {
// these members
};
class vertex : public connect_info {
// ...
};
// user-defined struct
class algo_vertex: public vertex {
// ...
};
members of connect_info class(I call it these members in this question) is only used in vertex class. But to keep the semantic of vertex class clear, I must separate these members to another base class(connect_info).
Problems generate here:
how can I hide these members from user-defined class? (protected and private are both useless now. If there is no connect_info base class, private can work well)
Does multi-layer inheritance design make sense in any situation?
Can virtual de-constructor function work well in multi-layer inheritance case?
You might need to move to has-a relationship, where connect_info can be an internal class(A class inside class) and make it private, if you want to hide connect_info members in user defined class.
class vertex {
// ...
private:
class connect_info{/*these members*/};
};
class algo_vertex : public vertex{
// connect_info members no longer accessible,
// unless you provide member functions in `vertex` to access it.
};
Inheritance is introducing strong coupling between classes, and is generally avoided. Instead, people are using composition. Read Prefer composition over inheritance question and answers.
In your specific example, what do you do, when you add algo_B_vertex class, where some of fields and methods from Vertex make no sense. Or in worse case scenario connect_info. Then you get into all sorts of problems. Not to mention complexity of several layers of inheritance.
how can I hide these members from user-defined class?
By using composition, and creating objects in private section.
Does multi-layer inheritance design make sense in any situation?
Of course it does. Fortunately that number of such situations is little. General advice is to think twice before jumping into multiple inheritance.
A good trade-of here would be to make vertexinherit privately from connect_info. The big difference with composition is that within the class vertex you can consider yourself being a connect_info, which means you will be able to access these members by doing this->member instead of connect_info_attribute.member. Also you won't need any friend or encapsulation hacks.
To sum it up, from the point of view of the child class, private inheritance means i consider myself being a "parent" but i don't want anyone else (not even my children) to consider me like one.

What is the practical use of protected inheritance?

Public inheritance is easy.
A : public B means every A is a B. In most programming language, like vb.net and objective-c, this is the only type of inheritance.
Private inheritance is also easy but pointless
A : private B means A is implemented by B. However, that's pointless because that means A should contain B instead. Ownership means less coupling with no disadvantage.
Then we have protected inheritance.
Can anyone explain to me what the hell is that for? Some says it's an "as a relationship". I am still not very clear on that.
Does anyone has some sample cases where people uses protected inheritance in good pattern (and conscience) for actual productive use?
Private inheritance is also easy but pointless
A : private B means A is implemented by B. However, that's pointless because that means A should contain B instead. Ownership means less coupling with no disadvantage.
That you might not see reasons for private inheritance does not mean it's pointless.
There are several cases where private inheritance has its reasons. You are right in that at a first glance, private inheritance means has-a relationships just like aggregation, and that private inheritance has a (slightly) tighter coupling.
Reasons for favouring private inheritance over aggretations could be some of the following:
With private inheritance you inherit typedefs as well. In some cases (e.g. traits classes) inheriting privatly is just the alternative to re-typedef tons of typedefs in the base class.
In seldom cases you have to initialize a member before a "real" (i.e. public) base class. The only way to achieve that is by making that member a private base class inherited before the public base.
Some times you need access to protected members of a member. If you can't change the member class itself, you have to use private inheritance to get access to them.
If a member has no data members of its own, it still occupies space. Making it a private base class enables the empty base class optimization, diminuishing the size of your class' objects.
for even more points, see James' comments below
These reasons are obviously technical reasons, some might even say "hacks". However, such reasons exist, so private inheritance is not completely pointless. It is just not "pure OO style" - but C++ isn't a pure OO language either.
The reason for protected inheritance are quite simple once you understood the ones for private inheritance:
If you have reasons to inherit something privately and want to make those benefits (i.e. that would-be member of your class or the typedefs) accessible to derived classes, use protected inheritance. Obviously, private inheritance should be used scarcely, and protected inheritance even more so.
The main motivation for protected inheritance is orthogonality.
in all other contexts, you have three different access controls:
private, protected and public. Why should inheritance be
different? In practice, one could argue that there is no need
or use for protected access in general. That may be overstating
the case, but it is certain that a lot less is protected than
private or public.
Also, private inheritance is not at all pointless, and in fact,
corresponds to the original use of inheritance. As soon as the
base class doing the implementing uses virtual functions which
the derived class has to overload, containment cannot be used.

Effective C++: discouraging protected inheritance?

I was reading Scott Meyers' Effective C++ (third edition), and in a paragraph in Item 32: Make sure public inheritance is "is-a" on page 151 he makes the comment (which I've put in bold):
This is true only for public inheritance. C++ will behave as I've described only if Student is publicly derived from Person. Private inheritance means something entirely different (see Item 39), and protected inheritance is something whose meaning eludes me to this day.
The question: how should I interpret this comment? Is Meyers trying to convey that protected inheritance is seldom considered useful and should be avoided?
(I've read the question
Difference between private, public, and protected inheritance as well as C++ FAQ Lite's private and protected inheritance section, both of which explain what protected inheritance means, but hasn't given me much insight into when or why it would be useful.)
Some scenarios where you'd want protected:
You have a base class with methods where you know you never want to expose the functionality outside, but you know will be useful for any derived class.
You have a base class with members that should be logically used by any class that extends that class, but should never be exposed outside.
Thanks to multiple inheritance you can play around with base classes' inheritance type and construct a more diversed class with existing logic and implementation.
A more concrete example:
You could create a few abstract classes that follow Design Pattern logic, lets say you have:
Observer
Subject
Factory
Now you want these all to be public, because in general, you could use the pattern on anything.
But, with protected inheritance, you can create a class that is an Observer and Subject, but only protected factory, so the factory part is only used in inherited classes. (Just chose random patterns for the example)
Another example:
Lets say for example you want to inherit from a library class (not that I encourage it). Lets say you want to make you own cool extension of std::list<> or a "better" shared_ptr.
You could derive protectedly from the base class (which is designed to have public methods).
This will give you the option to use your own custom methods, use the class' logic, and pass the logic to the to any derived class.
You could probably use encapsulation instead, but inheritance follows the proper logic of IS A
(or in this case IS sort of A)
He isn't exactly discouraging protected inheritance, he just says that he hasn't found any good use for it. I haven't seen anyone either elsewhere.
If you happen to find a couple of really useful use cases, you might have material to write a book too. :-)
Yup, there aren't many uses for protected or private inheritance. If you ever think about private inheritance, chances are composition is better suited for you. (Inheritance means 'is-a' and composition means 'has-a'.)
My guess is that the C++ committee simply added this in because it was very easy to do and they figured, "heck, maybe someone will find a good use for this". It's not a bad feature, it doesn't do any harm, just that no one has found any real use for it yet. :P
Yes and no. I myself think that protected inheritance is a bad feature too. It basicly imports all the base class's public and protected members as protected members.
I usually avoid protected members, but on the lowest levels requiring extreme efficiency with a compiler with bad link-time optimization they are useful. But everything built on that shouldn't be messing with the original base class's (data) members and use the interface instead.
What I think Scott Meyer is trying to say, is that you can still use protected inheritance if it solves a problem, but make sure to use comments to describe the inheritance because it's not semantically clear.
I don't know if Meyers is advising us to refrain from using protected inheritance, but it seems you should avoid it if Meyers is on your team, because at least he won't be able to understand your code.
Unless your co-workers know C++ better than he does, you should probably also stay away from protected inheritance. Everybody will understand the alternative, i.e. using composition.
I can imagine however a case where it could make sense: You need access to a protected member in a class whose code you can't change but you don't want to expose an IS-A relationship.
class A {
protected:
void f(); // <- I want to use this from B!
};
class B : protected A {
private:
void g() { f(); }
};
Even in that case, I would still consider making a wrapper with public inheritance that exposes the protected base members with public methods, then compose with these wrappers.
/*! Careful: exposes A::f, which wasn't meant to be public by its authors */
class AWithF: public A {
public:
void f() { A::f(); }
};
class B {
private:
AWithF m_a;
void g() { m_a.f(); }
};

Proper inheritance

What is meant by proper inheritance?
This thread gives a nice summary:
Proper inheritance occurs when the derived class "IS A" specialized type of the base class. Example Cat IS A Animal.
Improper inheritance occurs when a class is inherited from merely for code reuse without having any other relationship. Example Cat Inherits from Engine. A Cat is not an engine however both an engine and a cat purr.
I would like to add to what Justin and Baxter said.
The term proper inheritance is not really well-defined. Properly using inheritance is quite a subjective issue...
Consider the following example:
An interface: Bird
A concrete class: Ostrich
Should Ostrich inherits from Bird ? From a zoological point of view it makes sense, but from a Computer Science point of view... not so much. If Bird has a fly method, then how am I supposed to handle this in Ostrich::fly :x ?
There is somewhat of a war in the CS community. Indeed you'll regularly see books where Circle inherits from Ellipse (or the other way around) when it doesn't really makes sense from a CS point of view.
So my own little definition:
Considering that the interface defines precise semantics for each of its methods, a concrete class should only inherit from the interface if the implementation of each of the method matches the semantics specified.
Perhaps first we should recall what the value of inheritance itself is. Inheritance is a mechanism for both code reuse and interface reuse (polymorphism). But you can have code reuse without inheritance by using composition and delegation. And in many languages you can have polymorphism without inheritance, but not all languages. In a strongly typed language such as C++, polymorphism, which is itself another important code reuse mechanism, can only be achieved using inheritance. In fact, C++ distinguishes between public and private inheritance for interface and code reuse respectively. More on this later.
Generally one thinks of a class's methods as creating a contract with clients of the class: It guarantees that as long as you call a method having met certain preconditions, the method will deliver certain results. "Proper" inheritance is such that the subclass instance can be substituted for its parent class without violating the parent's contract. That is, none of the subclass's methods should override its base class's methods requiring stricter preconditions nor delivering more "less" results. Returning to C++, since there is a clear distinction between public and private inheritance where the former is required so that you may substitute a subclass instance for a base class instance, it is generally considered "proper" that the substitution be semantically correct. Otherwise why not use private inheritance?
Is Ostrich a valid subclass of Bird? It depends on what your abstraction of Bird is? If the Bird class has a method Bird::fly that does something tangible but Ostrich::fly overrides this to throw an exception and thus delivers "less" than its base class, I would say no. But if class Bird did not have a fly method (there is another subclass Flying_Bird that does), no problem.
My answer is that what holds for C++ is not a bad guideline for any object-oriented language. In a languages like Python where an inheritance hierarchy is not required for polymorphism, people might have a greater tendency to use inheritance just for code reuse. If this reuse is well-documented, it might not be an issue. But when I see a class hierarchy, my expectation is that a subclass is potentially going to be used polymorphically and thus an instance of the subclass can be substituted for an instance of the base class thereby obeyeing the Liskov substitution principle where a subclass is also a subtype.
When inheritance complies with a IS A relationship, as opposed to inheriting purely for code reuse without there being a logical subsumption of the child by the superclass.