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++中默认成员函数的析构函数,其余默认函数,请关注后续文章。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值