析构函数何时被调用

析构函数何时被调用

析构函数在下边3种情况时被调用:

  1. 对象生命周期结束,被销毁时;
  2. 主动调用delete ;
  3. 对象i是对象o的成员,o的析构函数被调用时,对象i的析构函数也被调用。

第一种情况

#include <iostream>

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

第二种情况

如果是new的对象,即使离开了作用域也会一直存在,必须主动delete,否则只有在结束程序时才会执行析构。这里在说下内存泄漏,举个例子

#include <iostream>

using namespace std;

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

此文章参考了:https://blog.csdn.net/weizhee/article/details/562833

猜你喜欢

转载自blog.csdn.net/chen134225/article/details/81221382