class shape {
public:
shape(int){}
};
class circle: public shape {
public:
circle(int): shape(1){}
};
class square: public shape {
public:
square(int): shape(1){}
};
class bizzare: public circle, public square {
public:
bizzare(): circle(1), square(1){}
};
這里用的就是一般的多重繼承,沒有虛擬繼承的存在。在bizzare(之所以叫這個名字,因為……從circle和square繼承而來實在是夠怪異的了,呵呵)類的member initialization list中,只需要寫circle和square類的構造函數就可以了,后兩者再分別調用它們的基類shape(分別的兩個實例)的構造函數。
而如果是虛擬繼承:
class shape {
public:
shape(int){}
};
class circle: public virtual shape {
public:
circle(int): shape(1){}
};
class square: public virtual shape {
public:
square(int): shape(1){}
};
class bizzare: public circle, public square {
public:
bizzare(): circle(1), square(1), shape(1){}
};
則必須在most derived的派生類中初始化虛擬基類。
TC++PL上肯定有說的,在class hierarchy那章。
這是語言規定。因為只有一個sharp對象,從哪個基類構造都有問題(因為它們可能調用虛基類的不同構造函數,產生二義性),所以標準規定必須在most derived構造時顯式或隱式(虛基類有缺省構造函數時)構造虛基類。樓主的例子里sharp沒有缺省構造函數,所以必須顯式構造。
TC++PL里有:
The constructor of a virtual base is invoked (implicitly or explicitly) from the constructor for the complete object (the constructor for the most derived class).
虛擬繼承:發生在多重繼承上,比如:一個類繼承兩類,但是這兩個類都繼承一個類。(類圖出現環),即“孫子”到“爺爺”的路徑超過一條時,使用,要不會有兩個“爺爺”
虛函數:與繼承完成多態工作。是面向對象關鍵中的關鍵。由于面向對象的設計是自頂向下的,先功能定義在實現。繼承主要有實現繼承和接口繼承,都需要多態