析構函數什麼時候被調用

析構函數什麼時候被調用
析構函數在下邊3種狀況時被調用:ios

對象生命週期結束,被銷燬時;
主動調用delete ;
對象i是對象o的成員,o的析構函數被調用時,對象i的析構函數也被調用。
第一種狀況函數

#include <iostream>spa

using namespace std;指針

class A
{
public:
    A()
    {
        cout << "constructing A" << endl;
    }
    ~A()
    {
        cout << "destructing A" << endl;
    }
private:
    int a;
};對象

void main()
{
    A a;
}

運行結果:生命週期

constructing A
destructing A
1
2
第二種狀況內存

若是是new的對象,即便離開了做用域也會一直存在,必須主動delete,不然只有在結束程序時纔會執行析構。這裏在說下內存泄漏,舉個例子作用域

#include <iostream>io

using namespace std;class

class A
{
public:
    A()
    {
        cout << "constructing A" << endl;
    }
    ~A()
    {
        cout << "destructing A" << endl;
    }
private:
    int a;
};

void fun() 
{
    A *a = new A();
}

int main() 
{
    while (1) 
    {
        fun();
    }
    return 0;
}

當離開fun時,雖然離開了做用域,但用new動態開闢空間的對象是不會析構的,你能夠觀察任務管理器,看到內存一直在上升。但你在其餘地方確沒法使用a所開闢的空間,由於a這個指針是保存在棧上的,當離開做用域後就自動析構(或者說自動消失了),但它所在分配空間是分配在堆上的,只有主動析構或程序結束,纔會釋放空間,也就是丟失了這塊空間的地址,沒法操做這塊空間了 。

第三種狀況

#include <iostream>

using namespace std;

class A
{
public:
    A()
    {
        cout << "constructing A" << endl;
    }
    ~A()
    {
        cout << "destructing A" << endl;
    }
private:
    int a;
};

class C
{
public:
    C()
    {
        cout << "constructing C" << endl;
    }
    ~C()
    {
        cout << "destructing C" << endl;
    }
private:
    int c;
};

class B : public A
{
public:
    B()
    {
        cout << "constructing B" << endl;
    }
    ~B()
    {
        cout << "destructing B" << endl;
    }
private:
    int b;
    C c;
};

void main()
{
    B b;
}

運行結果:

constructing A
constructing C
constructing B
destructing B
destructing C
destructing A

B的析構函數調用以後,又調用了B的成員c的析構函數 。

若將上邊的代碼中的main()函數內容改爲

 A* a = new B;

 delete a;

咱們知道,這將不會調用class B的析構函數不會被調用,因此class C的析構函數也不會被調用。

運行結果:

constructing A
constructing C
constructing B
destructing A

若將class A中的析構函數聲明爲虛函數 ,這時class B的析構函數也會被調用,例如:

#include <iostream>

using namespace std;

class A
{
public:
    A()
    {
        cout << "constructing A" << endl;
    }
    virtual ~A()
    {
        cout << "destructing A" << endl;
    }
private:
    int a;
};

class C
{
public:
    C()
    {
        cout << "constructing C" << endl;
    }
    ~C()
    {
        cout << "destructing C" << endl;
    }
private:
    int c;
};

class B : public A
{
public:
    B()
    {
        cout << "constructing B" << endl;
    }
    ~B()
    {
        cout << "destructing B" << endl;
    }
private:
    int b;
    C c;
};

void main()
{
    A* a = new B;

    delete a;
}

運行結果:

constructing A constructing C constructing B destructing B destructing C destructing A  

相關文章
相關標籤/搜索