C++繼承,多重繼承,虛繼承的構造函數以及析構函數的調用順序問題


 

#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的帶參數的構造函數。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM