C++ 类的默认成员函数-析构函数
个人主页:Jason_from_China-CSDN博客
所属栏目:C++系统性学习_Jason_from_China的博客-CSDN博客
所属栏目:C++知识点的补充_Jason_from_China的博客-CSDN博客
概念概述
- 默认成员函数就是用户没有显式实现,编译器会自动生成的成员函数称为默认成员函数。一个类,我们不写的情况下编译器会默认生成以下 6 个默认成员函数,需要注意的是这 6 个中最重要的是前 4 个,最后两个取地址重载不重要,我们稍微了解一下即可。其次就是 C++11 以后还会增加两个默认成员函数,移动构造和移动赋值,这个我们后面再讲解。默认成员函数很重要,也比较复杂,我们要从两个方面去学习。
包括
析构函数(~)
概念概述
析构函数与构造函数功能相反,析构函数不是完成对对象本身的销毁,比如局部对象是存在栈帧的,函数结束栈帧销毁,他就释放了,不需要我们管,C++规定对象在销毁时会自动调用析构函数,完成对象中资源的清理释放工作。析构函数的功能类比我们之前 Stack 实现的 Destroy 功能,而像 Date 没有 Destroy,其实就是没有资源需要释放,所以严格说 Date 是不需要析构函数的。
析构函数的特点:
- 析构函数名是在类名前加上字符 ~。
- 无参数无返回值。(这里跟构造类似,也不需要加 void)
- 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。
- 对象生命周期结束时,系统会自动调用析构函数。
- 跟构造函数类似,我们不写编译器自动生成的析构函数对内置类型成员不做处理,自定义类型成员会调用他的析构函数。
- 还需要注意的是我们显示写析构函数,对于自定义类型成员也会调用他的析构,也就是说自定义类型成员无论什么情况都会自动调用析构函数。
- 如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,如 Date;如果默认生成的析构就可以用,也就不需要显式写析构,如 MyQueue;但是有资源申请时,一定要自己写析构,否则会造成资源泄漏,如 Stack。
- 一个局部域的多个对象,C++规定后定义的先析构。
- 简单的说,析构函数就是函数的销毁,是编译器会自动调用的销毁
什么时候需要析构函数
当有资源申请的时候,就需要进行析构函数,析构函数是和构造函数一样的,内置类型不需要析构,自定义类型需要进行析构,也需要自己写析构函数,但是调用的时候是会自己调用的。
像如下图:此时开辟了空间,产生了资源的使用,所以就需要析构函数,如果在main函数调用结束的时候没有进行销毁资源,就会导致资源的泄露,这是很麻烦的。所以此时我们需要进行析构函数。
什么时候不需要析构函数
1,没有资源申请的时候
2,内置类型不做处理
3,两个栈实现队列的时候,内置类型不做处理,自定义类型会调用栈的析构(可以在队列的析构里面写一行,cout
但是这里有一个特殊情况,就是两个栈实现队列下面有其他资源
这里的指针需要析构,因为指向一个空间,需要把这个资源释放了
析构函数的使用
书写,其实就是C语言的函数的销毁
调用,main函数在结束的时候,会自动调用析构函数,因为这里有资源的申请
多个对象的时候,析构顺序
当有资源需要进行析构的时候,你没有写内容,但是定义了析构函数,也是会调用的,只是没有析构成功(析构函数的自动调用:当一个对象的生命周期结束时,如果该对象的类定义了析构函数,那么析构函数会被自动调用。这是由C++运行时环境保证的。如果没有定义析构函数,那么不会有任何特别的函数被调用来处理对象的销毁。)
规定来说哦,后定义的先析构
所以这里是st2先析构,st1后析构
析构函数调用的时候-注意事项
- 规定来说哦,后定义的先析构
- 类的析构函数调用一般是按照调用的相反顺序进行调用,但是需要注意static对象的存在,因为static改变了对象的生存作用域,需要等待程序结束的时候才会释放对象
- 全局变量先于局部对象进行构造。
(在 C++ 中,在程序启动时,全局变量的构造在进入
main
函数之前完成。也就是说,先构造全局变量,然后程序的执行流程进入
main
函数,再构造main
函数中的局部变量等。)- 局部对象按照出现的顺序进行构造,无论是否为static。(简单的说,也就是在main,调用Func函数,Func函数会按照后定义的先析构顺序进行析构)
- 题型精讲:
全局变量优先局部进行构造,所以往往最后进行析构。(C)
局部变量先构造的后析构。(A B)
被静态修饰的变量因为static改变了对象的生存作用域,需要等待程序结束的时候才会释放对象(D)