effective C++学习---条款8:别让异常逃离析构函数

本文探讨了在析构函数中处理异常的三种方法:异常捕捉与处理、异常捕获但不处理(吞掉异常)、预先处理潜在异常点。通过具体示例,详细解释了每种方法的实现方式及适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<iostream>
#include<vector>
using namespace std;

/*
本条款是处理析构函数中抛出异常的情况的
*/
class Widget{
public:
	~Widget(){}     //假设析构函中可能抛出异常
};
void doSomething()
{
	std::vector<Widget> v;
}//在函数结束后v就会被释放掉,并且v中存放的所有类对象也会调用析构函数进行空间释放
 //但是如果在调用某个析构函数时遇到错误并抛出了,那整个V的释放过程就中断了,这样就
 //产生了一种不确定性。至于为什么析构函数中会出现抛错呢,看看下面的例子

class DBConnection{  //这是一个数据库的连接类
public:
	static DBConnection create();//返回一个数据库的连接对象
	

	void close();  //关闭联机,失败则抛出异常
};
class DBConn{   //这是一个数据库的连接管理类
public:
	~DBConn()
	{
		db.close();//将关闭连接的操作放在析构函数中
	}              //这样析构函数就有了抛错的可能
private:
	DBConnection db;
};
//客户就会这样使用,创建一个连接对象给DBConn管理
{//在这个块运行结束后对象就会释放掉
	DBConn dbc(DBConnection::create());
}

/*
解决上述问题,我们有三个办法
//方法一:在析构函数中进行捕捉异常,然后进行处理
//方法二:将异常捕获但是不做处理(吞掉)
//方法三:把会产生错误的位置先让客户处理,然后再做“吞掉”处理
*/
//方法一:在析构函数中进行捕捉异常,然后进行处理
DBConn::~DBConn()
{
	try{
		db.close();
	}
	catch ("...")
	{
		std::abort();//直接终止程序,抢先制止“不明确行为”
	}
}
//方法二:将异常捕获但是不做处理(吞掉)
DBConn::~DBConn()
{
	try{
		db.close();
	}
	catch ("...")
	{
		//制作运转记录,记下close的调用失败
	}
	//这种情况析构函数可以正常执行完毕,也就是将错误吞掉了
}

//方法三:把会产生错误的位置先让客户处理,然后再做“吞掉”处理
class DBConn{
private:
	bool closed;
	DBConnection db;
public:
	void close()//让客户先对close进行一次处理,将析构中close的调用当成是双重保险
	{           //如果客户关成功了就不在析构函数中调用了
		db.close();
		closed = true;
	}
	~DBConn()
	{
		if (!closed)
		{
			try{
				db.close();
			}
			catch ("...")
			{
				//制作运转记录,记下close的调用失败
			}
			//这种情况析构函数可以正常执行完毕,也就是将错误吞掉了
		}
	}
};
//析构函数中注定是无法妥善处理异常的,所以我们会尽量让客户去处理异常,如果客户都没有处理
//那也不会埋怨析构函数的操作了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值