如果一個派生類從多個基類派生,而這些基類又有一個共同的基類,則在對該基類中聲明的名字進行訪問時,可能產生二義性
class A{public: int a;};
class A1:public A{public: int a1;};
class A2:public A{public: int a2;};
class B:public A1,public A2{public: int b;};
/////////main
{
B b;
b.A::a; //erroe 不知道從哪裏繼承
b.A1::a; //ok
b.A2::a; //ok
}
建立B類的對象時,A的構造函數被調用了兩次;一次是由A1調用,一次是由A2調用,所以初始化B的對象時包含了兩個A類的子對象。
總結:
1、如果一個派生類從多個基類派生,而這些基類又有一個共同的基類,則在對該基類中聲明的名字進行訪問時,可能產生二義性
2、 如果在多條繼承路徑上有一個公共的基類,那麼在繼承路徑的某處匯合點,這個公共基類就會在派生類的對象中產生多個基類子對象
3、 要使這個公共基類在派生類中只產生一個子對象,必須對這個基類聲明爲虛繼承,使這個基類成爲虛基類。
4、 虛繼承聲明使用關鍵字 virtual
class A{public: int a;};
class A1: virtual public A{public: int a1;};
class A2: virtual public A{public: int a2;};
class B:public A1,public A2{public: int b;};
/////////main
{
B b1;
b1.a; //ok
b1.A1::a; //ok
b1.A2::a; //ok
}
B的對象中只存在一個A類,因此通過B類對象直接訪問a,或者B.A1::a&B.A2::a,所訪問的都是那個唯一的基類子對象,引用時同一個基類A的子對象。
構造函數的調用次數:
//A類構造函數
//A1類構造函數
//A2類構造函數
//B類構造函數