Is it a good concept to use multiple inheritance or can I do other things instead?
Multiple inheritance (abbreviated as MI) smells, which means that usually, it was done for bad reasons, and it will blow back in the face of the maintainer.
This is true for inheritance, and so, it's even more true for multiple inheritance.
Does your object really needs to inherit from another? A
Car does not need to inherit from an
Engine to work, nor from a
Car has an
Engine and four
If you use multiple inheritance to resolve these problems instead of composition, then you've done something wrong.
Usually, you have a class
C both inherit from
A. And (don't ask me why) someone then decides that
D must inherit both from
I've encountered this kind of problem twice in 8 eights years, and it is amusing to see because of:
Dshould not have inherited from both
C), because this was bad architecture (in fact,
Cshould not have existed at all...)
Awas present twice in its grandchild class
D, and thus, updating one parent field
A::fieldmeant either updating it twice (through
C::field), or having something go silently wrong and crash, later (new a pointer in
B::field, and delete
Using the keyword virtual in C++ to qualify the inheritance avoids the double layout described above if this is not what you want, but anyway, in my experience, you're probably doing something wrong...
In Object hierarchy, you should try to keep the hierarchy as a Tree (a node has ONE parent), not as a graph.
The real problem with the Diamond of Dread in C++ (assuming the design is sound - have your code reviewed!), is that you need to make a choice:
Ato exist twice in your layout, and what does it mean? If yes, then by all means inherit from it twice.
This choice is inherent to the problem, and in C++, unlike other languages, you can actually do it without dogma forcing your design at language level.
But like all powers, with that power comes responsibility: Have your design reviewed.
Multiple inheritance of zero or one concrete classes, and zero or more interfaces is usually Okay, because you won't encounter the Diamond of Dread described above. In fact, this is how things are done in Java.
Usually, what you mean when C inherits from
B is that users can use
C as if it was a
A, and/or as if it was a
In C++, an interface is an abstract class which has:
The Multiple inheritance of zero to one real object, and zero or more interfaces is not considered "smelly" (at least, not as much).
First, the NVI pattern can be used to produce an interface, because the real criteria is to have no state (i.e. no member variables, except
this). Your abstract interface's point is to publish a contract ("you can call me this way, and this way"), nothing more, nothing less. The limitation of having only abstract virtual method should be a design choice, not an obligation.
Second, in C++, it makes sense to inherit virtually from abstract interfaces, (even with the additional cost/indirection). If you don't, and the interface inheritance appears multiple time in your hierarchy, then you'll have ambiguities.
Third, object orientation is great, but it is not The Only Truth Out ThereTM in C++. Use the right tools, and always remember you have other paradigms in C++ offering different kind of solutions.
C class is inheriting from
B are two unrelated objects (i.e. not in the same hierarchy, nothing in common, different concepts, etc.).
For example, you could have a system of
Nodes with X,Y,Z coordinates, able to do a lot of geometric calculations (perhaps a point, part of geometric objects) and each Node is an Automated Agent, able to communicate with other agents.
Perhaps you already have access to two libraries, each with its own namespace (another reason to use namespaces... But you use namespaces, don't you?), one being
geo and the other being
So you have your own
own::Node derive both from
This is the moment when you should ask yourself if you should not use composition instead. If
own::Node is really really both a
ai::Agent and a
geo::Point, then composition will not do.
Then you'll need multiple inheritance, having your
own::Node communicate with other agents according to their position in a 3D space.
(You'll note that
geo::Point are completely, totally, fully UNRELATED... This drastically reduces the danger of multiple inheritance)
There are other cases:
Sometimes you can use composition, and sometimes MI is better. The point is: You have a choice. Do it responsibly (and have your code reviewed).
Most of the time, in my experience, no. MI is not the right tool, even if it seems to work, because it can be used by the lazy to pile features together without realizing the consequences (like making a
Car both an
Engine and a
But sometimes, yes. And at that time, nothing will work better than MI.
But because MI is smelly, be prepared to defend your architecture in code reviews (and defending it is a good thing, because if you're not able to defend it, then you should not do it).
From an interview with Bjarne Stroustrup:
People quite correctly say that you don't need multiple inheritance, because anything you can do with multiple inheritance you can also do with single inheritance. You just use the delegation trick I mentioned. Furthermore, you don't need any inheritance at all, because anything you do with single inheritance you can also do without inheritance by forwarding through a class. Actually, you don't need any classes either, because you can do it all with pointers and data structures. But why would you want to do that? When is it convenient to use the language facilities? When would you prefer a workaround? I've seen cases where multiple inheritance is useful, and I've even seen cases where quite complicated multiple inheritance is useful. Generally, I prefer to use the facilities offered by the language to doing workarounds