#include <iostream> using namespace std; class A{ int data_a; public: A(){ data_a = 1; cout << "A" << endl; } A(int a){ data_a = a; cout << "A(a)" << endl; } void show(){ cout << data_a << endl; } ~A(){ cout << "~A" << endl; } }; class B :public A{ int data_b; public: B(){ data_b = 2; cout << "B" << endl; } B(int a, int b) :A(a){ data_b = b; cout << "B(a)" << endl; } void show(){ A::show(); cout << data_b << endl; } ~B(){ cout << "~B" << endl; } }; class C :public A{ int data_c; public: C(){ data_c = 3; cout << "C" << endl; } C(int a, int b) :A(a){ data_c = b; cout << "C(a)" << endl; } void show(){ A::show(); cout << data_c << endl; } ~C(){ cout << "~C" << endl; } }; class D :public B, public C{ int data_d; public: D(){ data_d = 4; cout << "D" << endl; } D(int a, int b, int c, int d) :B(a, b), C(a, c){ data_d = d; cout << "D(a)" << endl; } void show(){ B::show(); C::show(); cout << data_d << endl; } ~D(){ cout << "~D" << endl; } }; int main() { A a(1) ; B b(1,2); C c(1,3); D d(5,2,3,4); a.show(); b.show(); c.show(); d.show(); a.~A(); b.~B(); c.~C(); d.~D(); system("pause"); return 0; }
程序運行結果沒什么好說的。
下面開始變了:首先
class B :virtual public A{} class C :virtual public A{}
將B C都是虛繼承A,程序輸出如下:
這里可以看到當B和C都是虛繼承A的時候,在BC初始化的時候調用了A(a),在定義並初始化D的時候,只調用了一次A()(注意這里是A(),而不是A(a),因為子類中並沒有顯示的調用A的構造函數,所以默認調用A的無參構造函數),所以最終D輸出的值是1 2 1 3 4.同時在釋放的時候也只在最后調用一次A的析構函數。
現在將B和C依次變成虛繼承
1、B虛繼承A,C正常繼承。輸出如下:
2、C虛繼承A,B正常繼承。輸出如下:
這里可以看到總是先調用了A(),然后才依次調用帶參數的構造函數。所以這里可以看到show的值有不一樣的,因為虛繼承調用的是不帶參數的構造函數。另外調用了兩次A的構造函數因此也要調用兩次析構函數。注意析構函數的調用順序。
最后我們在D的構造函數中顯示的調用A的構造函數 同樣四種情況
D(int a, int b, int c, int d) :B(a, b), C(a, c),B::A(a){
這里A的構造函數分別限定使用B和C。以及B和C依次虛繼承。輸出如下:
可以看出,除了構造函數的調用遵循 先虛繼承后非虛繼承。但是都是調用了A的帶參數的構造函數。