我有以下C++代碼(VS2013如果該事項):C++虛繼承和構造
#include <iostream>
using namespace std;
struct A{
A() { cout << "A()" << endl; }
A(int i) { cout << "A(" << i << ")" << endl; }
};
struct B : /*virtual*/ public A{
B(int i) : A(i){ cout << "B(" << i << ")" << endl; }
};
struct C : /*virtual*/ public A{
C(int i) : A(i){ cout << "C(" << i << ")" << endl; }
};
struct D : /*virtual*/ public B, /*virtual*/ public C{
D() : B(2), C(3){ cout << "D()" << endl; }
};
void main() {
D d;
system("pause");
}
的代碼實現菱形繼承,用4個遺產總數: B:A,C: A,d:B,d:C
隨着無這些繼承設置爲virtual
,我得到以下輸出:
A(2)B(2)A(3)C(3) D()
這很有道理。 D()首先調用首先調用A(int x)的B(int x),然後調用首先調用A(int x)的C(int x),最後調用D()本身。
但是就虛擬繼承而言,我有4個繼承,這意味着我總共有16個虛擬\非虛擬繼承的組合。
在不同的選項中亂作一團會產生一些非常意想不到的結果,而我對虛擬繼承的瞭解越多,我似乎越感到困惑。
下面是一些例子:
- 當設置僅B:A至
virtual
我得到:
A()B(2)A(3)C(3)d ()
這是有道理的 - B實際上繼承了A,因此,除非特別聲明,否則B(int x)調用A的默認構造函數。
- 當是僅含有C設定:A到
virtual
我得到: - 當只有d設定:C到
virtual
我得到:
A()A(2)B(2)C(3)d()
爲什麼A的構造函數都在B和C之前?這種行爲對我來說毫無意義。
A(3)C(3)(2)B(2)d( )
爲什麼C的構造函數會先於B的?
我可以繼續下去。 其中一些組合會導致非常意想不到的結果(至少對我而言)。
我知道虛擬繼承的基礎知識,並通過簡單的例子來理解它們,並且我已經看到很多關於它的問題。但是其中一些行爲仍然困擾着我。
這些多重虛擬繼承是否有任何特定的規則集?
編輯: 我被重定向到這個問題: Mixing virtual and non-virtual inheritance of a base class Whlie,幫助了很多,我作爲其中A的構造函數在任何特定情況被稱爲仍然感到困惑。 我仍然需要一些幫助。