析构函数

在之前的博客中,我们介绍了构造函数和拷贝构造函数。他们的作用都是将对象进行初始化。今天,我要介绍在类中的另一种函数,叫做析构函数。

析构函数的函数名为~+类名。和构造函数一样,析构函数也是没有返回值的,也不用写void。但是由于它没有任何参数,所以它肯定是不能被重载的。若用户没有定义析构函数,那么系统会自动生成一个析构函数,这个析构函数并不起任何作用。

析构函数在对象被销毁之前被自动调用,它的作用是将对象中的成员占用的内存归还给操作系统。为了观察析构函数被调用的时机,我们在析构函数下加上打印析构函数名的代码,看它在控制台中被打印出来的位置。

#include <iostream>
#include <string>
using namespace std;

class Student
{
public:
    Student()
    {
        cout << "Student()" << endl;
    }
    ~Student()
    {
        cout << "~Student()" << endl;
    }
private:
    string m_strName;
};

int main(void)
{
    Student stu;
    system("PAUSE");
    return EXIT_SUCCESS;
}

我们写了这样的一串代码,在类中定义了构造函数和析构函数,由于我们没有在函数定义里写任何有实际意义的代码,所以这两个函数不起任何实际作用,只是“刷一下存在感”,在调用的时候打印一行字。在main函数中,我们只是实例化了一个对象,不对对象进行任何操作。


运行结果1_1

这个时候,我们看到,只调用了构造函数,析构函数还是没有被调用。这时候,我们按下任意键。


运行结果1_2

可以看到,在程序结束运行之后,析构函数被调用了出来。这就说明了,如果从栈中实例化一个对象,那么对象会在程序结束后被自动销毁,内存会被自动归还,析构函数也在这个时候被调用。

那么,如果是从堆中实例化对象,那么析构函数会在哪里被调用呢?我们将main函数改成这样。

int main(void)
{
    Student* p = new Student();
    delete p;
    p = NULL;
    system("PAUSE");
    return EXIT_SUCCESS;
}

我们从堆中实例化了一个对象指针p,不进行任何操作,直接释放内存,然后使指针悬空。我们看一下运行结果。


运行结果2

我们发现,程序还没有结束运行,析构函数就已经被调用。这也就说明了,从堆中实例化对象,在执行delete的时候被手动销毁,这个时候系统就会调用析构函数。

这一次,我们主要讲解析构函数在什么时候会被调用,如果想知道析构函数如何发挥它真正的作用,我们会在用到对象成员指针的时候进行介绍。

以上就是此篇博客的内容,下一篇:对象数组。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容