[英]Multiple inheritance
我有2個基類(B1和B2),它們來自公共基類(B),它們有一個公共變量(let: int x;
來自基數B),第一個基數x=0
,第二個基數x=10
(B1,B2構造函數中給出的默認值)。
視覺:
class B
{
int x;
protected:
B(int x) : x{x}{}
};
class B1 : public B
{
protected:
B1() : B(0){}
};
class B2 : public B
{
protected:
B2() : B(10){}
};
現在,如果我再推導一個類:
class D : virtual public B1, virtual public B2
{
public:
D() : B1{}, B2{}{}
};
這里只有一個x副本可用於虛擬概念,現在如果我嘗試使用派生類對象訪問x值,x的實例將在O / p( x=0
或x=10
)中得到,為什么?
為了使用虛擬繼承,必須在B1
和B2
中將基數B
聲明為虛擬。 沒有它,你有B的非虛擬繼承。
如果你有非虛擬繼承,那么你在D
有兩個B
基,所以你不能在D
訪問x
而不將其限定為B1::x
或B2::x
如果你有虛擬繼承,那么你只有一個B
和一個x
,所以它的兩個賦值( x=0
和x=10
)將按你執行的順序發生,而后者中的任何一個都將覆蓋該值由前一個設置(與具有兩個賦值的簡單變量x
)。
在您的設置中, B
實際上並不是虛擬繼承的,因為您必須在B1
和B2
聲明B
虛擬繼承(如果預期兩個“分支”預期,它總是必須發生在最低級別)在類繼承層次結構中合並得更高,即
class B1 : virtual public B
{
protected:
B1() : B(0){}
};
class B2 : virtual public B
{
protected:
B2() : B(10){}
};
如果這樣做, B
初始化將完全不同,因為構建虛擬基類有特殊規則:
在虛擬繼承中,虛擬基類始終由派生程度最高的類初始化。 因此,正如您已經將D
的構造函數實現為
D() : B1(), B2(){}
因此,不要顯式調用您的B
構造函數,編譯器將假定您要調用B
的默認構造函數。 但是你的B
類沒有默認的構造函數,所以你會得到一個像這樣的編譯器錯誤:
prog.cpp: In constructor ‘D::D()’:
prog.cpp:31:20: error: no matching function for call to ‘B::B()’
D() : B1(), B2(){}
^
因此,你必須做類似的事情
class D : public B1, public B2
{
public:
D() : B(99), B1(), B2(){}
};
這也解決了你的問題: x
的值將是大多數派生類想要的值(在這種情況下為99)。 因此,沒有歧義。
PS:你也看到,你的問題是為什么有最大派生類的虛擬基類構造的特殊規則是有意義的核心。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.