C++从入门到精通——类的6个默认成员函数之析构函数
时间:2024-04-20 13:45:32 来源:网络cs 作者:晨起 栏目:国内电商 阅读:
析构函数
前言一、析构函数的概念二、析构函数的特性三、析构函数的练习题四、总结
前言
类的6个默认成员函数:如果一个类中什么成员都没有,简称为空类。
空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。
默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。
class Date {};
一、析构函数的概念
通过前面构造函数的学习,我们知道一个对象是怎么来的,那一个对象又是怎么没呢的?
析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。
在C++中,析构函数是一种特殊的成员函数,用于在对象被销毁时清理其使用的资源。它的名称与类的名称相同,前面加上一个波浪线(~
),没有返回类型,也不接受任何参数。
当对象的生命周期结束时,即对象超出了其作用域,或者通过delete
运算符释放了动态分配的内存,或者程序执行完成时,都会触发对象的析构函数。
析构函数可以用于释放动态分配的内存、关闭打开的文件、释放其他资源等。它的主要作用是确保对象在被销毁之前进行必要的清理工作,以避免资源泄漏和不可预测的行为。
二、析构函数的特性
析构函数是特殊的成员函数,其特征如下:
析构函数名是在类名前加上字符~
。无参数无返回值类型。一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构函数不能重载对象生命周期结束时,C++编译系统系统自动调用析构函数。 typedef int DataType;class Stack{public:Stack(size_t capacity = 3){_array = (DataType*)malloc(sizeof(DataType) * capacity);if (NULL == _array){perror("malloc申请空间失败!!!");return;}_capacity = capacity;_size = 0;}void Push(DataType data){// CheckCapacity();_array[_size] = data;_size++;}// 其他方法...~Stack(){if (_array){free(_array);_array = NULL;_capacity = 0;_size = 0;}}private:DataType* _array;int _capacity;int _size;};void TestStack(){Stack s;s.Push(1);s.Push(2);}
关于编译器自动生成的析构函数,是否会完成一些事情呢?下面的程序我们会看到,编译器生成的默认析构函数,对自定类型成员调用它的析构函数。跟构造函数类似,内置类型不做处理,自定义类型调用它的析构函数。 class Time{public:~Time(){cout << "~Time()" << endl;}private:int _hour;int _minute;int _second;};class Date{private:// 基本类型(内置类型)int _year = 1970;int _month = 1;int _day = 1;// 自定义类型Time _t;};int main(){Date d;return 0;}
程序运行结束后输出:~Time()
在main
方法中根本没有直接创建Time
类的对象,为什么最后会调用Time
类的析构函数?
因为:main
方法中创建了Date
对象d
,而d
中包含4个成员变量,其中_year
, _month
, _day
三个是内置类型成员,销毁时不需要资源清理,最后系统直接将其内存回收即可;而_t
是Time
类对象,所以在d
销毁时,要将其内部包含的Time
类的_t
对象销毁,所以要调用Time
类的析构函数。但是:main
函数 中不能直接调用Time
类的析构函数,实际要释放的是Date
类对象,所以编译器会调用Date
类的析构函数,而Date
没有显式提供,则编译器会给Date
类生成一个默认的析构函数,目的是在其内部调用Time
类的析构函数,即当Date
对象销毁时,要保证其内部每个自定义对象都可以正确销毁 main
函数中并没有直接调用Time
类析构函数,而是显式调用编译器为Date
类生成的默认析构函数
注意:创建哪个类的对象则调用该类的析构函数,销毁那个类的对象则调用该类的析构函数
Date
类;有资源申请时,一定要写,否则会造成资源泄漏,比如Stack
类。 三、析构函数的练习题
两个栈实现一个队列
四、总结
有资源需要显示清理,就需要写析构函数。如Stack
List
没有资源需要清理,如Date
(日期类),内置类型成员没有资源需要清理。剩下的都是自定义类型成员。如MyQueue
,这些场景都不需要写析构函数 阅读本书更多章节>>>>
本文链接:https://www.kjpai.cn/guonei/2024-04-20/160667.html,文章来源:网络cs,作者:晨起,版权归作者所有,如需转载请注明来源和作者,否则将追究法律责任!
上一篇:叶柒柒凌御阳小说 第1章
下一篇:返回列表