由於C++中允許多繼承,所以會出現二義性問題:在多個派生類中,定義了相同名字的方法,這時再在main函數裡面通過基類調用該方法時,編譯器就犯難了。因為它不知道你到底是想用哪一個派生類裡面的方法。
那麼,現在又有了一個問題:假如有兩個派生類DerivedA和DerivedB,它們的同名方法一個有參數,一個沒有參數,是不是不會出現二義性問題了?
或者說,這兩個派生類方法的一個是private,一個是public,是不是就可以防止二義性了呢?
答案是否定的。二義性的檢查應在訪問控制權限或者類型檢查之前進行,因此訪問控制權限不同或類型不同不能解決二義性問題。
既然上述提出的假設成立,那麼應該怎樣去有效的解決二義性問題呢?
虛基類就是為了這個解決這種二義性問題提出來的。
二義性產生的最主要原因是:基類在派生類中產生了兩個子對象,從而導致了對基類成員訪問的不唯一性。所以只需要使公共基類只產生一個子對象,就可以了。
也就是說,保證虛基類構造函數只被調用一次即可。虛基類自對象是由最派生類的構造函數通過調用虛基類的構造函數實現,此時,最派生類的所有基類中列出的對虛基類的構造函數的調用在執行過程中都將被忽略,而從保證對虛基類自對象值初始化一次。同時,最派生類的初始化列表必須列出對虛基類構造函數的調用;如果未列出,則表示使用該虛基類的默認構造函數。
(在繼承結構的層次中,建立的對象屬於這個結構中間的某個類,建立對象時所制定的類就是最派生類)
下面通過一個小例子分析一下:
#include <iostream>
using namespace std;
//基類
class Base
{
//公有成員
public:
Base(char i)
{
cout << "Base's cons." << i<< endl;
}
~Base()
{
cout << "Base's des." << endl;
}
};
//派生類1
class Derivedl1:virtual public Base
{
//公有成員
public:
Derivedl1(char i,char j):Base(i)
{
cout << "Derivedl1's cons." << j<< endl;
}
~Derivedl1()
{
cout << "Derived's des." << endl;
}
//私有成員
private:
char b;
};
//派生類2
class Derivedl2:virtual public Base
{
//公有成員
public:
Derivedl2(char i,char j):Base(i)
{
cout << "Derivedl2' cons." << j <<endl;
}
~Derivedl2()
{
cout << "Derived12' des." << endl;
}
};
//繼承基類Base的派生類
class Derived2: public Derivedl1,public Derivedl2
{
//公有成員
public :
Derived2(char i,char j,char k,char l,char m,char n)
:Derivedl2(k,l),Derivedl1(i,j),Base(i),aa(m)
{
cout << "Derived2's cons." <<n << endl;
}
~Derived2()
{
cout << "Derived2's des." << endl;
}
//私有成員
private :
Base aa;
};
//main函數
int main()
{
Derived2 obj('a','b','c','d','e','f');
return 0;
}