The Solution
We can re-declare our classes as follows:
class Animal { public: virtual void eat; }; // Two classes virtually inheriting Animal: class Mammal : public virtual Animal { public: virtual void breathe; }; class WingedAnimal : public virtual Animal { public: virtual void flap; }; // A bat is still a winged mammal class Bat : public Mammal, public WingedAnimal { };The Animal
portion of Bat::WingedAnimal
is now the same Animal
instance as the one used by Bat::Mammal
, which is to say that a Bat
has only one, shared, Animal
instance in its representation and so a call to Bat::eat
is unambiguous. Additionally, a direct cast from Bat
to Animal
is also unambiguous, now that there exists only one Animal
instance which Bat
could be converted to.
This is implemented by providing Mammal
and WingedAnimal
with a vtable pointer (or "vpointer") since the memory offset between the beginning of a Mammal
and of its Animal
part is unknown until runtime. Thus Bat becomes (vpointer
, Mammal
, vpointer
, WingedAnimal
, Bat
, Animal
). There are two vtable pointers, one per inheritance hierarchy that virtually inherits Animal
. In this example, one for Mammal
and one for WingedAnimal
. The object size has therefore increased by two pointers, but now there is only one Animal
and no ambiguity. All objects of type Bat
will have the same vpointers, but each Bat
object will contain its own unique Animal
object. If another class inherits from Mammal
, such as Squirrel
, then the vpointer in the Mammal
object in a Squirrel
will be different from the vpointer in the Mammal
object in a Bat
, although they can still be essentially the same in the special case that the Squirrel
part of the object has the same size as the Bat
part, because then the distance from the Mammal
to the Animal
part is the same. The vtables are not really the same, but all essential information in them (the distance) is.
Read more about this topic: Virtual Inheritance
Famous quotes containing the word solution:
“All the followers of science are fully persuaded that the processes of investigation, if only pushed far enough, will give one certain solution to each question to which they can be applied.... This great law is embodied in the conception of truth and reality. The opinion which is fated to be ultimately agreed to by all who investigate is what we mean by the truth, and the object represented in this opinion is the real.”
—Charles Sanders Peirce (18391914)
“Any solution to a problem changes the problem.”
—R.W. (Richard William)