【C++】深入剖析默认成员函数2:析构函数
【C++】深入剖析默认成员函数2:析构函数
继上一个有点令我头大的构造函数后,真是一波未平一波又起呀,咱们又迎来新的默认成员函数:析构函数!
别说,我真的一脸懵了~
上一篇构造函数,我们简单地了解到了第一个默认成员函数---构造函数的各种便利,总而言之,构造函数就是初始化一个对象,那清理一个对象----便是析构函数咯。
在数据结构中我们有实现过Init(初始化,也可以看做相似于构造函数),destroy(销毁,就可以看做相似于析构函数)
析构函数的概念:
析构函数与构造函数功能相反,构造函数主要是初始化,但不开空间
析构函数主要清理但不销毁对象
这样理解还是很容易的
析构函数的特点:
同样的,析构函数也是特殊的默认成员函数,有以下特点:
- 1.析构函数名是在类名前加上字符 ~。
- 2. ⽆参数⽆返回值。 (这⾥跟构造类似,也不需要加void)
- .⼀个类只能有⼀个析构函数。若未显式定义,系统会⾃动⽣成默认的析构函数。
- 4. 对象⽣命周期结束时,系统会⾃动调⽤析构函数。
Date类:
代码示例:
代码语言:javascript代码运行次数:0运行复制class Date
{
public:
Date(int year = 1, int month = 1, int day = 0) {
_year = year;
_month = month;
_day = day;
}
void Print() {
cout << _year << "-" << _month << "-" << _day << endl;
}
~Date() {
cout << "~Date()" << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
d1.Print();
return 0;
}
运行结果:
我们从这里可以看出,析构函数自动调用啦!
析构函数还有一个特性:先进行构造的对象后析构:
代码示例如下:
代码语言:javascript代码运行次数:0运行复制class Date
{
public:
Date(int year = 1, int month = 1, int day = 0) {
_year = year;
_month = month;
_day = day;
}
void Print() {
cout << _year << "-" << _month << "-" << _day << endl;
}
~Date() {
cout << "~Date()" << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Date d1;
Date d2(2024, 12, 21);
return 0;
}
运行结果:
第一个箭头析构的是对象d2,第二个就是对象d1哒
刚刚上面使用了常见的日期类来做举例,接下来就要用我们熟悉的老朋友Stack类来举个例子啦
Stack类:
代码如下:
代码语言:javascript代码运行次数:0运行复制typedef int STDataType;
class Stack
{
public:
Stack(int n = 4)
{
_a = (STDataType*)malloc(sizeof(STDataType) * n);
if (nullptr == _a)
{
perror("malloc申请空间失败");
return;
}
_capacity = n;
_top = 0;
}
~Stack()
{
cout << "~Stack()" << endl;
free(_a);
_a = nullptr;
_top = _capacity = 0;
}
private:
STDataType* _a;
size_t _capacity;
size_t _top;
};
int main()
{
Stack st1;
Stack st2(10);
return 0;
}
运行结果:
在此相应的上面一个箭头是st2的析构,下面一个箭头是st1的析构
重点:
就是Stack类的析构不能单纯地靠编译器给的默认析构函数来进行析构,这样会造成资源的泄露,因为Stack类中有进行资源的申请,一定要自己写析构!!!
当然还有一个MyQueue类也是不需要我们去实现析构的
MyQueue类:
代码实现如下:
代码语言:javascript代码运行次数:0运行复制typedef int STDataType;
class Stack
{
public:
Stack(int n = 4)
{
_a = (STDataType*)malloc(sizeof(STDataType) * n);
if (nullptr == _a)
{
perror("malloc申请空间失败");
return;
}
_capacity = n;
_top = 0;
}
~Stack()
{
cout << "~Stack()" << endl;
free(_a);
_a = nullptr;
_top = _capacity = 0;
}
private:
STDataType* _a;
size_t _capacity;
size_t _top;
};
// 两个Stack实现队列
class MyQueue
{
public:
//编译器默认⽣成MyQueue的析构函数调⽤了Stack的析构,释放的Stack内部的资源
// 显⽰写析构,也会⾃动调⽤Stack的析构
~MyQueue() {
cout << "MyQueue()" << endl;
}
private:
Stack pushst;
Stack popst;
};
int main()
{
Stack st1;
Stack st2(10);
MyQueue mq;
return 0;
}
运行结果:
这就是MyQueue类的析构,这就很有趣啦,因为MyQueue类是使用了Stack类中的资源,而没有自己创建资源,所以可以使用编译器生成的默认析构函数。
析构函数的补充要点:
跟构造函数类似,我们不写编译器⾃动⽣成的析构函数对内置类型成员不做处理,⾃定类型成员会调⽤他的析构函数。 (对于内置类型的成员变量,不做处理;对于自定义类型的成员变量,会自动调用默认的析构函数)
还需要注意的是我们显⽰写析构函数,对于⾃定义类型成员也会调⽤他的析构,也就是说⾃定义类
型成员⽆论什么情况都会⾃动调⽤析构函数。
总而言之,就是编译器总会在你需要的时候出手帮你,但你也不能完全靠编译器。
以上就是对于析构函数的理解
有问题希望佬们及时指出哦~
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2024-12-21,如有侵权请联系 cloudcommunity@tencent 删除stack编译器对象函数c++#感谢您对电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格的认可,转载请说明来源于"电脑配置推荐网 - 最新i3 i5 i7组装电脑配置单推荐报价格
推荐阅读
留言与评论(共有 6 条评论) |
本站网友 奥运海报 | 14分钟前 发表 |
也会⾃动调⽤Stack的析构 ~MyQueue() { cout << "MyQueue()" << endl; } private | |
本站网友 宁海房屋出租 | 26分钟前 发表 |
系统会⾃动⽣成默认的析构函数 | |
本站网友 蔓延视觉婚纱摄影 | 4分钟前 发表 |
也会⾃动调⽤Stack的析构 ~MyQueue() { cout << "MyQueue()" << endl; } private | |
本站网友 老人之恋 | 12分钟前 发表 |
如有侵权请联系 cloudcommunity@tencent 删除前往查看stack编译器对象函数c++ | |
本站网友 assembly文件夹 | 6分钟前 发表 |
一定要自己写析构!!!当然还有一个MyQueue类也是不需要我们去实现析构的MyQueue类:代码实现如下:代码语言:javascript代码运行次数:0运行复制typedef int STDataType; class Stack { public |