| Virtual Inheritance |
Article Index for Virtual |
Website Links For Virtual |
Information AboutVirtual Inheritance |
| CATEGORIES ABOUT VIRTUAL INHERITANCE | |
| object-oriented programming | |
| c | |
|
In C++ , virtual inheritance is a kind of inheritance that solves some of the problems caused by Multiple Inheritance (particularly the " Diamond Problem ") by clarifying ambiguity over which ancestor class members to use. It is used when inheritance is representing restrictions of a set rather than composition of parts. A multiply-inherited base class is denoted as virtual with the virtual Keyword .THE PROBLEM Consider the following class hierarchy. class Animal { public: virtual void eat(); }; class Mammal : public Animal { public: virtual Color getHairColor(); }; class WingedAnimal : public Animal { public: virtual void flap(); }; // A bat is a winged mammal class Bat : public Mammal, public WingedAnimal {}; But how does a Bat Eat()? As declared above, a call to Bat.Eat() is ambiguous. One would have to call either Bat.WingedAnimal.Animal::Eat() or Bat.Mammal.Animal::Eat(). The problem is that semantics of conventional multiple inheritance do not model reality. In a sense, an Animal is only an Animal once; a Bat is a Mammal and a WingedAnimal, but the Animalness of a Bat's Mammalness is the same Animalness as that of its WingedAnimalness. This situation is sometimes referred to as diamond inheritance and is a problem that virtual inheritance works, in part, to solve. CLASS REPRESENTATION Before going further it is helpful to consider how Classes Are Represented In C++ . In particular, inheritance is simply a matter of putting parent and child class one after the other in memory. Thus Bat is really (Animal,Mammal,Animal,WingedAnimal,Bat) which makes Animal duplicated, causing the ambiguity. SOLUTION We can redeclare our classes as follows: // Two classes virtually inheriting Animal: class Mammal : public virtual Animal { public: virtual Color getHairColor(); }; class WingedAnimal : public virtual Animal { public: virtual void flap(); }; // A bat is still a winged mammal class Bat : public Mammal, public WingedAnimal {}; Now the Animal portion of Bat::WingedAnimal is the ''same'' Animal as the one used by Bat::Mammal, which is to say that a Bat has only one Animal in its representation and so a call to Bat::Eat() is unambiguous.
|
|
|