The Problem
Consider the following class hierarchy.
class Animal { public: virtual void eat; }; class Mammal : public Animal { public: virtual void breathe; }; class WingedAnimal : public Animal { public: virtual void flap; }; // A bat is a winged mammal class Bat : public Mammal, public WingedAnimal { }; Bat bat;As declared above, a call to bat.eat
is ambiguous because there are two Animal
(indirect) base classes in Bat
, so any Bat
object has two different Animal
base class subobjects. So an attempt to directly bind a reference to the Animal
subobject of a Bat
object would fail, since the binding is inherently ambiguous:
To disambiguate, one would have to explicitly convert bat
to either base class subobject:
In order to call eat
, the same disambiguation is needed: static_cast
or static_cast
.
In this case, the double inheritance of Animal
is probably unwanted, as we want to model that the relation (Bat
is an Animal
) exists only once; that a Bat
is a Mammal
and is a WingedAnimal
does not imply that it is an Animal
twice: an Animal
base class corresponds to a contract that Bat
implements (the "is a" relationship above really means "implements the requirements of"), and a Bat
only implements the Animal
contract once. The real world meaning of "is a only once" is that Bat
should have only one way of implementing eat
, not two different ways, depending on whether the Mammal
view of the Bat
is eating, or the WingedAnimal
view of the Bat
. (In the first code example we see that eat
is not overridden in either Mammal
or WingedAnimal
, so the two Animal
subobjects will actually behave the same, but this is just a degenerate case, and that does not make a difference from the C++ point of view.)
This situation is sometimes referred to as diamond inheritance (see Diamond problem) because the inheritance diagram is in the shape of a diamond. Virtual inheritance can help to solve this problem.
Read more about this topic: Virtual Inheritance
Famous quotes containing the word problem:
“Every reform was once a private opinion, and when it shall be a private opinion again, it will solve the problem of the age.”
—Ralph Waldo Emerson (1803–1882)
“The disesteem into which moralists have fallen is due at bottom to their failure to see that in an age like this one the function of the moralist is not to exhort men to be good but to elucidate what the good is. The problem of sanctions is secondary.”
—Walter Lippmann (1889–1974)