析构函数何时被调用

in 编程
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9

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

对象生命周期结束,被销毁时;
主动调用delete ;
对象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
1
2
第二种情况

如果是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

 

关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9
扫一扫关注公众号添加购物返利助手,领红包
Comments are closed.

推荐使用阿里云服务器

超多优惠券

服务器最低一折,一年不到100!

朕已阅去看看