Prevent exceptions from leaving destructions
动机
- 一种情况下,如果析构函数抛出了异常,则该异常点后面的程序将无法执行,而如果这些对象不能正常释放,则有可能造成内存泄漏的情况;
- 另一种情况则是,假设前面有异常被抛出,而后面的对象仍在执行正常的销毁,而此时后面的对象也抛出了异常,在两个异常同时存在的情况下,会导致不明确行为,程序崩溃。
方法
如果析构函数不得已执行一个有可能抛出异常的动作,那可以用两个方法解决:
- 让析构函数自行处理
1 | DBConn::~DBConn() |
- 直接结束程序
1 | DBConn::~DBConn() |
有时候,析构函数处理掉异常不是一件好事,因为我们不知道“某些行为失败了”;但有时为了让程序忽略掉错误继续运行,这又是一件好事。
- 也可以重新设计接口,让客户自身去处理异常,比如上面代码的close()函数;
1 | class DBConn{ |
建议
- 析构函数不能抛出异常。如果实在要抛出异常,可以选择让析构函数捕捉该异常,并使其限制在析构函数内或者直接结束函数;
- 如果客户需要对某个操作函数的异常做出反应,我们应该为其提供一个普通函数,而不是在析构函数中执行该操作;