版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_31880107/article/details/86551095
提出问题
被同学问到这样一个问题:
下面这段程序运行的时候,没有运行析构函数?
class test
{
int a;
public:
test()
~test(){ cout << "进入析构函数" << endl;}
}
int main()
{
test B;
system(pause);
return 0;
}
问题出在system(pause)
这里。
对象的销毁
在C++中如果定义了对象,并且对象中定义了变量等,那么程序运行的时候就会给它分配内存,如果不手动销毁的话,对象会一直存在的,这些内存会一直被占用,这是一个很严重的问题。
之前的方法是在每一个class中都定义一个free函数,在free函数中执行释放内存的命令。
class Test
{
int* a;
public:
Test() {a = new int;}
void free() {delete a;}
};
这种方法有个很明显的缺点, 必须手动销毁,也就是说程序员必须自己判断变量什么时候不用了,然后手动销毁。所以如果程序员判断错了,或者忘了销毁,同样会出问题。
析构函数
C++ 11标准之后,有一个新的处理方法:析构函数。可以理解为:析构函数是与构造函数功能相反的,析构函数专门用于清理内存。
- 析构函数的定义:~ClassName()
- 析构函数没有参数,没有返回值
- 析构函数是程序自动调用的,不需要手动调用
- 析构函数是对象释放系统资源的保障
- 当类中定义了构造函数,并且构造函数中使用了系统资源,则需要自定义析构函数
问题分析
析构函数是在对象销毁的时候自动调用的,如果对象还在使用中,程序是不会调用析构函数的。
class test
{
int a;
public:
test()
~test(){ cout << "进入析构函数" << endl;}
}
int main()
{
test B;
system(pause);
return 0;
}
在初学C++的时候,为了能够看到程序的执行结果,防止出现一闪而过的情况,会在主程序中加上system(pause)
,但是这个时候,程序运行到这里就不会继续往下运行了,而这时,对象B还在使用中,所以这个时候是没有释放B的内存的,当然也就不会进入析构函数:~test()
。
在初学的时候,为了能够观察到真的进入了析构函数,可以使用其他的方法来保持控制台命令窗口,但是必须要运行到return 0
。其中一个方法就是进入调试程序,在return 0
的这句话前面加上断点,这样程序运行到了这里,但是还没有退出,所以可以观察到析构函数的运行。