当前位置: 首页 > article >正文

C++入门——(类的默认成员函数)析构函数

文章目录

  • 一、析构函数
  • 二、析构函数的特点
  • 总结


一、析构函数

析构函数与构造函数功能相反,析构函数不是完成对对象本⾝的销毁,⽐如局部对象是存在栈帧的,函数结束栈帧销毁,他就释放了,不需要我们管,C++规定对象在销毁时会⾃动调⽤析构函数,完成对象中资源的清理释放⼯作。析构函数的功能类⽐我们之前Stack实现的Destroy功能。

二、析构函数的特点

  • 1.析构函数名是在类名前加上字符 ~
  • 2.⽆参数⽆返回值。 (这⾥跟构造类似,也不需要加void)
    关于构造函数,请看博主之前构造函数的文章
    构造函数
  • 3.⼀个类只能有⼀个析构函数。若未显式定义,系统会⾃动⽣成默认的析构函数。
class Stack
{
public:
	//全缺省的默认构造函数
	Stack(int n = 4)
	{
		_a = (int*)malloc(n * sizeof(int));
		_capacity = n;
		_top = 0;
	}

	//析构函数
	~Stack()
	{

	}

private:
	int* _a;
	int _capacity;
	int _top;
};
  • 4.对象⽣命周期结束时,系统会⾃动调⽤析构函数。
class Stack
{
public:
	//全缺省的默认构造函数
	Stack(int n = 4)
	{
		_a = (int*)malloc(n * sizeof(int));
		_capacity = n;
		_top = 0;
	}

	//析构函数
	~Stack()
	{
		cout << "~Stack()" << endl;//并非析构函数就是打印,这里只是为了看的更清楚
	}

private:
	int* _a;
	int _capacity;
	int _top;
};


int main()
{
	Stack st;

	return 0;
}

在这里插入图片描述
注意看,在main函数中我们并没有调用析构函数~Stack,但是打印了结果。这说明析构函数确实是自动调用的。
这里将析构函数写成了打印的形式,是为了更加直观的感受它的自动调用,而不是析构函数就是打印。
真正的析构函数:(类似于C语言定义栈的destroy函数)

	//析构函数
	~Stack()
	{
		//cout << "~Stack()" << endl;
		free(_a);
		_a = nullptr;
		_top = _capacity = 0;
	}
  • 5.跟构造函数类似,我们不写编译器⾃动⽣成的析构函数对内置类型成员不做处理,⾃定类型成员会调⽤他的析构函数。
    自定义类型和内置类型,同样在构造函数那一章有写。
  • 6.还需要注意的是我们显⽰写析构函数,对于⾃定义类型成员也会调⽤他的析构,也就是说⾃定义类型成员⽆论什么情况都会⾃动调⽤析构函数。
    比如两个栈实现队列时,我们队列不写析构函数,在程序结束时,也会去自动调用栈的析构函数。
class Stack
{
public:
	//全缺省的默认构造函数
	Stack(int n = 4)
	{
		_a = (int*)malloc(n * sizeof(int));
		_capacity = n;
		_top = 0;
	}

	//析构函数
	~Stack()
	{
		cout << "~Stack()" << endl;
		free(_a);
		_a = nullptr;
		_top = _capacity = 0;
	}

private:
	int* _a;
	int _capacity;
	int _top;
};
//定义队列的结构
class MyQueue
{
	Stack _pushst;
	Stack _popst;
};


int main()
{
	MyQueue q;
	return 0;
}

在这里插入图片描述
由运行结果可以看到,程序中并没有调用MyQueue的析构函数,但打印了两次~Stack(),也就是说调用了两次Stack的析构函数
如果我们写了,依旧会去调用Stack的析构函数:

class Stack
{
public:
	//全缺省的默认构造函数
	Stack(int n = 4)
	{
		_a = (int*)malloc(n * sizeof(int));
		_capacity = n;
		_top = 0;
	}

	//析构函数
	~Stack()
	{
		cout << "~Stack()" << endl;
		free(_a);
		_a = nullptr;
		_top = _capacity = 0;
	}

private:
	int* _a;
	int _capacity;
	int _top;
};
//定义队列的结构
class MyQueue
{
public:
	~MyQueue()
	{
		cout << "~MyQueue()" << endl;
	}
private:
	Stack _pushst;
	Stack _popst;
};

int main()
{
	MyQueue q;
	return 0;
}

在这里插入图片描述
从运行结果可以看到,既调用了MyQueue的析构函数,也调用了Stack的析构函数

  • 7.如果类中没有申请资源时,析构函数可以不写,直接使⽤编译器⽣成的默认析构函数,如Date;
    如果默认⽣成的析构就可以⽤,也就不需要显⽰写析构,如MyQueue;
    但是有资源申请时,⼀定要⾃⼰写析构,否则会造成资源泄漏,如Stack。
class Date
{
public:
	 构造函数,类名就是函数名
	函数没有返回值,所以函数没有类型
	//构造函数也可以写成缺省参数
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
private:
	// 这⾥只是声明,没有开空间
	// 不需要析构函数
	int _year;
	int _month;
	int _day;
};
  • 8.⼀个局部域的多个对象,C++规定后定义的先析构。
#include<iostream>
using namespace std;
class Date
{
public:
	//构造函数也可以写成缺省参数
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	~Date()
	{
		cout << "~Date()" << endl;
	}
	void Print()
	{
		cout << _year << "/" << _month << "/" << _day << endl;
	}
private:
	// 这⾥只是声明,没有开空间
	int _year;
	int _month;
	int _day;
};

class Stack
{
public:
	//全缺省的默认构造函数
	Stack(int n = 4)
	{
		_a = (int*)malloc(n * sizeof(int));
		_capacity = n;
		_top = 0;
	}

	//析构函数
	~Stack()
	{
		cout << "~Stack()" << endl;
		free(_a);
		_a = nullptr;
		_top = _capacity = 0;
	}

private:
	int* _a;
	int _capacity;
	int _top;
};

class MyQueue
{
public:
	~MyQueue()
	{
		cout << "~MyQueue()" << endl;
	}
private:
	Stack _pushst;
	Stack _popst;
};


int main()
{
	Date d1;
	Stack st;
	MyQueue q;
	return 0;
}

在这里插入图片描述
注意这里先定义的是d1,但却是最后调用析构函数的。


总结

以上就是今天要讲的内容,本文介绍了C++中默认成员函数的析构函数,其余默认函数,请关注后续文章。


http://www.kler.cn/news/316054.html

相关文章:

  • 数据库基础知识---------------------------(3)
  • 早期病毒和反病毒技术(网络安全小知识)
  • MATLAB系列08:输入/输入函数
  • SSCMS 插件示例 一插件创建及插件菜单
  • 大厂面试真题:SpringBoot的核心注解
  • FastAPI 的隐藏宝石:自动生成 TypeScript 客户端
  • Golang | Leetcode Golang题解之第423题从英文中重建数字
  • C++学习
  • 机器学习——Bagging
  • String类和String类常用方法
  • LinuxC高级作业1
  • css边框修饰
  • 代码随想录:打家劫舍||
  • 鸿蒙OpenHarmony【轻量系统内核扩展组件(CPU占用率)】子系统开发
  • 【C++】面向对象编程的三大特性:深入解析继承机制
  • Open3D(C++) 基于点云的曲率提取特征点(自定义阈值法)
  • Unity DOTS系列之IJobChunk来迭代处理数据
  • 速盾:高防cdn防御的时候会封ip吗?
  • GPTo1论文详解
  • ICML 2024 论文分享┆用于高分辨率图像合成的可扩展修正流Transformers
  • 深度学习与应用:行人跟踪
  • 使用Docker快速搭建Airflow+MySQL详细教程
  • 【Linux篇】常用命令及操作技巧(基础篇)
  • IM项目-----消息转发子服务
  • 开源模型应用落地-qwen模型小试-调用Qwen2-VL-7B-Instruct-更清晰地看世界-集成vLLM(二)
  • 运行在docker环境下的图片压缩小工具
  • Qt集成Direct2D绘制,实现离屏渲染
  • OpenHarmony(鸿蒙南向开发)——轻量系统内核(LiteOS-M)【SHELL】
  • ARM中的寄存器
  • Zabbix 6.4添加中文语言