Effective C++ 条款08:别让异常逃离析构函数

规则一 析构函数绝对不要吐出异常

如果析构函数中的某些操作可能导致异常,就记得捕捉异常。

class DBConn {
public:
	...
	~DBConn() {
		try {db.close();}
		catch (...) {
			// 制作运转纪录,记下对close的调用失败
			// 终止程序,析构函数不要吐出异常
			std::abort();
		}
	}
};

规则二 将异常处理转移给用户

class DBConn {
public:
	...
	void close() {		// 提供用户使用的新函数
		db.close();
		closed = true;
	}
	~DBConn() {
		if (!closed) {
			try {		// 双重保险,如果用户忘记关闭连接的话
				db.close();
			}
			catch (...) {	// 如果关闭动作失败,记录下来并结束程序或吞下异常
				// 制作运转记录,记下对close的调用失败;
				...
			}
		}	
	}
private:
	DBConnection db;
	bool closed;
};

提供给用户新的函数调用,这样就可以把异常处理转交给用户,再析构函数中还需再次捕捉异常,是为了双重保险。

总结

  1. 析构函数绝对不要吐出异常。如果一个被析构函数调用的函数可能抛出异常,析构函数就应该捕捉任何异常,然后吞下它们(不传播)或者结束程序。
  2. 如果客户需要对某个操作函数运行期间抛出的异常做出反应,那么class应该提供一个普通函数(而非在析构函数中)执行该操作。
原文地址:https://www.cnblogs.com/zhonghuasong/p/7353842.html