在 C++ 里,虛基類是用來解決菱形繼承問題的。菱形繼承問題是指當一個派生類從兩個或更多基類派生,而這些基類又從同一個基類派生時,派生類會包含多份間接基類的數據副本,這可能會引發數據冗余和二義性問題。虛基類可以保證在派生類中只存在一份間接基類的數據副本。
下面是一個 C++11 中使用虛基類的例子:
#include <iostream>// 基類
class Animal {
public:Animal() {std::cout << "Animal constructor" << std::endl;}void eat() {std::cout << "Animal is eating" << std::endl;}
};// 中間派生類,使用虛繼承
class Mammal : virtual public Animal {
public:Mammal() {std::cout << "Mammal constructor" << std::endl;}
};// 中間派生類,使用虛繼承
class Bird : virtual public Animal {
public:Bird() {std::cout << "Bird constructor" << std::endl;}
};// 最終派生類,繼承自 Mammal 和 Bird
class Bat : public Mammal, public Bird {
public:Bat() {std::cout << "Bat constructor" << std::endl;}
};int main() {Bat bat;bat.eat();return 0;
}
代碼解釋:
Animal
?類:這是最基礎的類,有一個構造函數和?eat
?方法。Mammal
?類和?Bird
?類:它們都虛繼承自?Animal
?類,這意味著在后續的派生類中,Animal
?類的數據成員和成員函數只會有一份副本。Bat
?類:它從?Mammal
?類和?Bird
?類派生。由于?Mammal
?和?Bird
?是虛繼承?Animal
,所以?Bat
?類中只有一份?Animal
?類的數據副本。main
?函數:創建一個?Bat
?對象并調用?eat
?方法。因為?Bat
?類中只有一份?Animal
?類的數據副本,所以調用?eat
?方法時不會產生二義性。
? ? ?運行這個程序,你會看到?Animal
?類的構造函數只被調用了一次,這就表明在?Bat
?類中只有一份?Animal
?類的數據副本。