構造和解構函式呼叫順序

SJLin96發表於2018-08-21

參考文章:

C++中建構函式與解構函式的呼叫順序

C++建構函式和解構函式的呼叫順序

 

一. 理論

1. 建構函式和解構函式

①建構函式

  • 建構函式不能有返回值
  • 預設建構函式時,系統將自動呼叫該預設建構函式初始化物件,預設建構函式會將所有資料成員都初始化為零或空 
  • 建立一個物件時,系統自動呼叫建構函式

②解構函式

  • 解構函式沒有引數,也沒有返回值。不能過載,也就是說,一個類中只可能定義一個解構函式
  • 如果一個類中沒有定義解構函式,系統也會自動生成一個預設的解構函式,為空函式,什麼都不做
  • 呼叫條件:1.在函式體內定義的物件,當函式執行結束時,該物件所在類的解構函式會被自動呼叫;2.用new運算子動態構建的物件,在使用delete運算子釋放它時。

③拷貝建構函式

  • 拷貝建構函式實際上也是建構函式,具有一般建構函式的所有特性,其名字也與所屬類名相同。拷貝建構函式中只有一個引數,這個引數是對某個同類物件的引用。它在三種情況下被呼叫:
  • 用類的一個已知的物件去初始化該類的另一個物件時;
  • 函式的形參是類的物件,呼叫函式進行形參和實參的結合時;
  • 函式的返回值是類的物件,函式執行完返回撥用者。

2. 建構函式的呼叫順序 

基類建構函式、物件成員建構函式、派生類本身的建構函式  

3. 解構函式的呼叫順序

派生類本身的解構函式、物件成員解構函式、基類解構函式(與構造順序正好相反) 

4. 特例 

區域性物件,在退出程式塊時析構

靜態物件,在定義所在檔案結束時析構

全域性物件,在程式結束時析構 

繼承物件,先析構派生類,再析構父類 

物件成員,先析構類物件,再析構物件成員

 

二. 例子

#include <iostream>
using namespace std;

class Base1
{
public:
    Base1(void){cnt++;cout<<"Base1::constructor("<<cnt<<")"<<endl;}
    ~Base1(void){cnt--;cout<<"Base1::deconstructor("<<cnt + 1<<")"<<endl;}
private:
    static int cnt;
};
int Base1::cnt = 0;

class Base2
{
public:
    Base2(int m){num = m; cout<<"Base2::constructor("<<num<<")"<<endl;}
    ~Base2(void){cout<<"Base2::deconstructor("<<num<<")"<<endl;}
private:
    int num;
};

class Example
{
public:
    Example(int n){num = n; cout<<"Example::constructor("<<num<<")"<<endl;}
    ~Example(void){cout<<"Example::deconstructor("<<num<<")"<<endl;}
private:
    int num;
};

class Derived:public Base1, public Base2
{
public:
    Derived(int m, int n):Base2(m),ex(n){cnt++;cout<<"Derived::constructor("<<cnt<<")"<<endl;}
    ~Derived(void){cnt--;cout<<"Derived::deconstructor("<<cnt+1<<")"<<endl;}
private:
    Example ex;
    static Example stex;    //Example::constructor(1) //不能輸出
    static int cnt;
};
int Derived::cnt = 0;

Derived ge_a(1,2); // Base1::constructor(1)
                   // Base2::constructor(1)
                   // Example::constructor(2)
                   // Derived::constructor(1)
static Derived gs_b(3,4);   // Base1::constructor(2)
                            // Base2::constructor(3)
                            // Example::constructor(4)
                            // Derived::constructor(2)
int main(void)
{
    cout << "---------start---------" << endl;
    Derived d(5,6); // Base1::constructor(3)
                    // Base2::constructor(5)
                    // Example::constructor(6)
                    // Derived::constructor(3)
    Derived e(7,8); // Base1::constructor(4)
                    // Base2::constructor(7)
                    // Example::constructor(8)
                    // Derived::constructor(4)
    cout << "----------end----------" << endl;

    //Derived e(7,8) 析構
            // Derived::deconstructor(4)
            // Example::deconstructor(8)
            // Base2::deconstructor(7)
            // Base1::deconstructor(4)

    //Derived d(5,6) 析構
            // Derived::deconstructor(3)
            // Example::deconstructor(6)
            // Base2::deconstructor(5)
            // Base1::deconstructor(3)
    return 0;
}
//static Derived gs_b(3,4) 析構
        // Derived::deconstructor(2)
        // Example::deconstructor(4)
        // Base2::deconstructor(3)
        // Base1::deconstructor(2)
//Derived ge_a(1,2) 析構
        // Derived::deconstructor(1)
        // Example::deconstructor(2)
        // Base2::deconstructor(1)
        // Base1::deconstructor(1)

//static Example stex 析構
        //Example::deconstructor(1) //不能輸出

 

#include <iostream>
using namespace std;
class A
{
public:
     A(){cout<<"A::constructor"<<endl;};
     ~A(){cout<<"A::deconstructor"<<endl;};
};
class B
{
public:
     B(){cout<<"B::constructor"<<endl;};
     ~B(){cout<<"B::deconstructor"<<endl;};
};
class C : public A
{
public:
     C(){cout<<"C::constructor"<<endl;};
     ~C(){cout<<"C::deconstructor"<<endl;};
private:
//    static B b;
     B b;
};
class D : public C
{
public:
     D(){cout<<"D::constructor"<<endl;};
     ~D(){cout<<"D::deconstructor"<<endl;};
};

int main(void)
{
    C* pd = new D();
    delete pd;
    return 0;
}
/* Output
----->B b
A::constructor
B::constructor
C::constructor
D::constructor
C::deconstructor
B::deconstructor
A::deconstructor

----->static B b
A::constructor
C::constructor
D::constructor
C::deconstructor
A::deconstructor
 */

 

相關文章