C++primer 学习笔记13章析构函数

析构函数

波浪号加类名构成,没有返回值,也不接受参数
(由于不接受参数,因此它不能被重载)

作用

构造函数初始化对象的非static数据成员,析构函数释放对象所使用资源,并销毁对象的非static数据成员

执行顺序

构造函数中,成员初始化是在函数体执行之前完成的,且按照他们在类内出现的顺序进行初始化,析构函数中,首先执行函数体,然后销毁成员,成员按照初始化顺序的逆序销毁,所以析构函数可以执行设计者想要的任何收尾工作,再销毁成员

成员的销毁完全依赖于其本身的类型

成员的销毁完全依赖于其本身的类型,类类型需要执行自身的析构函数,而内置类型则什么也不做(无析构函数)

隐式销毁一个内置指针类型的成员不会delete它所指向的对象的原因

你觉得需要delete,那么这个指针必然是通过new构造的,但是事实上:

  1. 它可以指向一个栈上的地址
  2. 它可以指向别的类的成员
  3. 它可以与别的new构造的指针有alias
  4. 它可以是由new []或者malloc构造的…

这样的情况是不可能穷尽的,编译器也不可能记录下来具体是那种情况,并且分别采取对应的措施。

调用析构函数的情况:

1:变量离开作用域时被销毁
2:当对象被销毁,其成员被销毁
3:容器(无论是标准库容器还是数组)被销毁,成员被销毁
4:动态分配的对象,指针被delete时
5:临时对象(格式:类名()),创建的完整表达式结束时

class Sales_data
{
public:
	Sales_data(const Sales_data&);
	Sales_data();
	Sales_data& operator=(const Sales_data&);
	~Sales_data() { std::cout<<bookNo<<" delete" << std::endl; }
	std::string bookNo;
	int units_sold = 0;
	double revenue = 0.0;
};
Sales_data::Sales_data(const Sales_data& orgig):bookNo(orgig.bookNo),units_sold(orgig.units_sold),revenue(orgig.revenue)
{
	using namespace std;
	cout << " copy Sales_data" << endl;
}

Sales_data::Sales_data()
{
	using namespace std;
	cout << " init Sales_data" << endl;
}

	Sales_data* p = new Sales_data; 
	p->bookNo = "1";
	auto p2 = std::make_shared<Sales_data>();
	p2->bookNo = "2";
	Sales_data item(*p); // 对象被销毁时,其成员被销毁
	item.bookNo = "item p";
	vector<Sales_data> vec; 
	vec.push_back(*p2); // 容器被销毁时,其元素被销毁
	vec[0].bookNo = "vec p2";
	delete p; // 动态分配的对象,指针被delete时
	/*
		退出局部作用域时,item,p2和vec调用析构函数	
	*/

输出结果
在这里插入图片描述

当指向对象的引用或指针离开作用域时,析构函数不会执行

class Sales_data
{
public:
	Sales_data(const Sales_data&);
	Sales_data();
	Sales_data& operator=(const Sales_data&);
	~Sales_data() { std::cout<<bookNo<<" delete" << std::endl; }
	std::string bookNo;
	int units_sold = 0;
	double revenue = 0.0;
};
Sales_data::Sales_data(const Sales_data& orgig):bookNo(orgig.bookNo),units_sold(orgig.units_sold),revenue(orgig.revenue)
{
	using namespace std;
	cout << " copy Sales_data" << endl;
}

Sales_data::Sales_data()
{
	using namespace std;
	cout << " init Sales_data" << endl;
}

	Sales_data sales_data;
	sales_data.bookNo = "bookNo";
	Sales_data& sales_data1 = sales_data;
	Sales_data* sales_data2 = &sales_data;
	//退出局部作用域时 ,sales_data 调用析构函数 
	//sales_data1和sales_data2不调用析构函数

输出结果:
在这里插入图片描述

析构函数体自身并不直接销毁成员

析构函数体自身并不直接销毁成员,成员是在析构函数体之后隐含的析构阶段中被销毁的。在整个对象销毁过程重视那个,析构函数体是作为成员销毁步骤之外的另一部分进行的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值