c++析构函数

 析构函数的概念

与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成
的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作

析构函数的特性

1、析构函数名是在类名前加上字符 ~。

2、无参数无返回值类型。

3、一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构函数不能重载。

4、对象生命周期结束时,C++编译系统系统自动调用析构函数。

以下三种情况是否需要写析构函数:

有动态申请资源 ,需要显式写析构函数

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

class Stack
{
public:
	Stack(int defaultcapacity=4)
	{
		cout << "Stack(int defaultcapacity=4)" << endl;
		_a = (int*)malloc(sizeof(int) * defaultcapacity);
		if (_a == nullptr)
		{
			perror("malloc fail");
			return;
		}

		_top = 0;
		_capacity = defaultcapacity;
	}

	void push(int x)
	{
		_a[_top] = x;
		_top++;
	}

	void pop()
	{
		_top--;
	}

	void print()
	{
		cout << _a[_top-1] << endl;
	}

	void Destroy()
	{
		cout << "estroy()" << endl;
		free(_a);
		_a = nullptr;

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

int main()
{
	Stack st1;

	st1.Destroy();
	return 0;
}

最后打印的结果是

可以看到,我们调用了Destroy函数,所以打印了estroy,那如果我们不调用呢?系统会自己生成一个给我们吗?看下面的情况。

看框中的代码,只创建了一个成员,调试到目前为止,系统自动调用构造函数对st1进行了初始化。需要注意的是,在上述代码中,我们写了构造函数Stack,但是没有写析构函数,以观察系统是否会自动生成。 

  根据上图,我们发现,尽管已经出了函数的作用域,但是却并没有清理,表示系统没有自己生成并调用析构函数。基于此,我们如果写一个不是内置类型的变量,是需要自己写析构函数的。

观察下图,我们自己写了一个析构函数,但是没有调用,看看系统会不会自动调用析构函数。

调试到此,表示系统自动调用了构造函数。

根据打印的结果和调试的结果可以看出,系统自动调用了析构函数。

总结:有动态申请资源的,需要自己写析构函数,但是系统会帮你自动调用

 无动态申请资源,不需要写析构函数

class Data
{
public:
	Data(int year=2,int month=2,int day=2)
	{
		_year = year;
		_month = month;
		_day = day;
	}

	void print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

	//没有动态申请资源,都是内置类型,栈帧结束,系统自动回收,不用写析构函数
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1;
	
	d1.print();
	return 0;
}

对于像日期类这种没有动态申请资源,全是内置类型的类,不需要写析构函数,因为都是存在栈区的,调用结束,系统自动回收。

原理很简单,他们是在栈区的,本来就不需要进行Destroy。

总结:对于没有动态申请资源的,不需要写析构函数。

需要释放成员都是自定义类型,不需要写析构函数,系统会调用它的析构函数(构造函数同理)

观察下面的代码,是用两个栈创建一个队列,成员都是Stack,所以系统会自动调用构造和析构函数,进入Stack,Stack里面有构造和析构函数,所以会自动调用,最后给到这个q1。

 看下面的图,明明我们创建的是Myqueue的变量,最后自动调用的是Stack的构造函数和析构函数。

 这张图表示,我们进入调试,发现系统跳到了Stack的构造函数那里,表示Myqueue的构造函数是由Stack实现的,因为,Myqueue是由Stack实现的。

 这张图表示,进入调试,系统自动跳到了Stack的析构函数那里,表示最终由Stack的析构函数实现。

总结:对于需要释放资源的成员都是自定义成员的,不需要写析构函数,系统会自动调用。

构造函数和析构函数都是:不要你再去手动调用了,系统会自动调用,解决了忘记调用的问题。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值