Effective C++ —— 别让异常逃离析构函数
来源:互联网 发布:网络评选投票 编辑:程序博客网 时间:2024/06/11 15:35
C++ 并不禁止析构函数吐出异常,但不鼓励这么做。
1.如果一个被析构函数调用的函数可能抛出异常,则析构函数应该捕获这些异常,然后终止程序或吞下它们。
2.如果客户需要对某个函数在运行中抛出的异常做出反应,那么这个类应该提供一个普通函数(非析构函数)执行该操作。
class Widget{ public: Widget(); ~Widget() {}};void work(){ std::vector<Widget> v;}
v在销毁时有责任销毁容器内的所有Widget 对象,如果在销毁第一个对象时抛出了异常,剩下的对象还是应该被销毁。如果第二个对象被销毁时又出现了异常,这时对于C++而言异常有些多了,程序不是结束执行就是导致不明确行为。
使用标准库容器或数组等都有可能出现这样的情况,其实只要析构函数吐出异常,程序都会出现这样的问题。
第二个例子:DBConnection 类负责数据库连接
class DBConnection
{
public:
static DBConnection Create();
private:
void close();//关闭联机,释放资源,失败则抛出异常
};
为确保客户不忘记调用close()方法来释放资源,可以设计一个数据库资源管理类,在其析构函数中调用close().
class DBResManager
{
public:
DBResManager();
~DBResManager()
{
db.close();
}
private:
DBConnection db;
};
close()调用成功,一切都美好,一旦异常抛出,则DBResManager析构函数会传播异常。两个解决方案:
一.调用abort()终止程序
DBResManager::~DBResManager(){try{ db.close();}catch(){ std::abort();//终止程序,避免异常传播}}
二.吞下异常
DBResManager::~DBResManager(){try{ db.close();}catch(){ //吞下异常,程序继续执行,保证程序可以继续可靠执行}}
最好的方案是:重新设计DBResManager类的接口,让客户有机会处理异常
class DBResManager{ public: DBResManager(); void close() { db.close(); closed = true; } ~DBResManager() { if(!closed) { try { db.close(); } catch() { //吞下异常,程序继续执行,保证程序可以继续可靠执行 } } private: DBConnection db; bool closed;};
说明:当某个操作在失败时可能抛出异常,又必须对这个异常进行处理时,那么这个处理函数必须是非析构函数。因为在析构函数中抛出异常是个很糟糕的想法,结果就是过早地结束程序或发生不明确的行为。
- Effective C++——》 条款08:别让异常逃离析构函数
- Effective c++学习笔记——条款08:别让异常逃离析构函数
- Effective c++学习笔记——条款08:别让异常逃离析构函数
- Effective c++学习笔记——条款08:别让异常逃离析构函数
- Effective C++ —— 别让异常逃离析构函数
- effective c++ 别让异常逃离析构函数
- 《Effective C++》学习笔记条款08 别让异常逃离析构函数
- Effective C++:条款08:别让异常逃离析构函数!
- [Effective C++]条款08 别让异常逃离析构函数
- 读书笔记《Effective C++》条款08:别让异常逃离析构函数
- 别让异常逃离析构函数
- Effective C++笔记之五 别让异常逃离析构函数
- Effective C++学记之08 别让异常逃离析构函数
- Effective C++ 条款08 别让异常逃离析构函数
- Effective C++ Item 8 别让异常逃离析构函数
- Effective C++读书笔记之八:别让异常逃离析构函数
- Effective C++ Item 8 别让异常逃离析构函数
- Effective C++ Item 08-别让异常逃离析构函数
- 禁止浏览器缓存- make sure web page is not cached
- 实现ListView的 分页加载,通过点击按钮实现
- HDU 4252A Famous City
- 删除字符串中连续字符
- leetcode刷题,总结,记录,备忘 283
- Effective C++ —— 别让异常逃离析构函数
- Struts、hibernate、Spring 官网下载步骤
- C# 反射实例 一
- iOS中Bitcode的介绍及配置
- SQL Server数据库
- Python 标准库——collections(下)
- 关于ListView触摸事件和点击Item事件冲突解决方法
- [速报酱]速报酱团队第一周
- 嵌入式Linux系统内核Kernel(裁减移植)启动调试技术(回顾)