仮想継承
From Wikipedia, the free encyclopedia
次のようなクラス階層を考える。
class Animal
{
public:
virtual void eat();
};
class Mammal : public Animal
{
public:
virtual Color getHairColor();
};
class WingedAnimal : public Animal
{
public:
virtual void flap();
};
// Bat(こうもり)は翼のある哺乳類(winged mammal)である
class Bat : public Mammal, public WingedAnimal {};
Bat bat;
bat の eat() メソッドを呼び出した場合、どうなるだろうか? 上の宣言では bat.eat() の呼び出しは曖昧である。bat.WingedAnimal.Animal::eat() なのか bat.Mammal.Animal::eat() なのか判らない。問題は、いわゆる多重継承の意味論が現実をモデル化したものではない点にある。感覚的に言えば、Animal が Animal でしかないように、Bat は Mammal であると同時に WingedAnimal である。しかしBat(こうもり)のMammal(哺乳類)性におけるAnimal(動物)性は、WingedAnimal(翼のある動物)性におけるAnimal(動物)性と同じである。
このような状況を菱形継承と呼び、これを解決するのが仮想継承である。