In C++ a class can inherit (directly or indirectly) from more than one class, which is referred to as
multiple inheritance.
C# and Java, however, limit classes to single inheritance each class inherits
from a single parent class.
Multiple inheritance is a useful way to create classes that combine aspects of two disparate class
hierarchies, something that often happens when using different class frameworks within a single
application.
If two frameworks define their own base classes for exceptions, for example, you can
use multiple inheritance to create exception classes that can be used with either framework.
The problem with multiple inheritance is that it can lead to ambiguity. The classic example is when
a class inherits from two other classes, each of which inherits from the same class:
class A {
protected:
bool flag;
};
class B : public A {};
class C : public A {};
class D : public B, public C {
public:
void setFlag( bool nflag ){
flag = nflag; // ambiguous
}
};
In this example, the flag data member is defined by class A. But class D descends from class B
and class C, which both derive from A, so in essence two copies of flag are available because two
instances of A are in D’s class hierarchy. Which one do you want to set? The compiler will complain
that the reference to flag in D is ambiguous. One fix is to explicitly disambiguate the reference:
B::flag = nflag;
Another fix is to declare B and C as virtual base classes, which means that only one copy of A can
exist in the hierarchy, eliminating any ambiguity.
Other complexities exist with multiple inheritance, such as the order in which the base classes are
initialized when a derived object is constructed, or the way members can be inadvertently hidden
from derived classes. To avoid these complexities, some languages restrict themselves to the simpler single inheritance model.
Although this does simplify inheritance considerably, it also limits its usefulness
because only classes with a common ancestor can share behaviors. Interfaces mitigate this
restriction somewhat by allowing classes in different hierarchies to expose common interfaces even
if they’re not implemented by sharing code.