博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Effective C++ --008]别让异常逃离析构函数
阅读量:4347 次
发布时间:2019-06-07

本文共 1653 字,大约阅读时间需要 5 分钟。

这章非常容易理解:因为C++并不禁止析构函数吐出异常,只是不鼓励这样做而已。

一、原因

假设我们有10个装着鸡蛋的容器,而且现在我们还想着把它在析构函数打烂。

class Egg {public :     ...     ~Egg() {          // 这里可能出错,导致蛋打不烂     }};void foo() {      vector
v // 假设v中间有10个Egg ....} // v在这里被自动销毁

 如果我们在销毁10个鸡蛋的过程中,在析构第一个鸡蛋的时候,有个异常被抛出,按照销毁机制,后续的9个鸡蛋还是需要被销毁的(否则鸡蛋保存的任何资源都会发生泄漏)。

但是如果后面的鸡蛋仍然抛出异常,在两个异常同时存在的情况下,C++程序会结束执行或者出现不明确的行为。

就算是使用STL的其他容器,还是会发生同样的问题。

为什么呢?因为C++不鼓励析构函数吐出异常。

二、详解

为了方便上面的原因理解,我们可以来尝试一下的例子:

class DB {public :     ....     static DB create() ;//函数返回DB对象     void close();        //关闭数据库的联机,失败则抛出异常    }

 

 

如果为了方便其他人员使用DB类,防止在调用DB的时候忘记关闭连接,那么我们可以贴心一下:

class DBC {public :     ....     ~DBC() {       // 确保每次调析构的时候都会关闭连接                db.close();        }private:     DB db;}

 

其他人直接使用DBC的类就好了,但是如果这样写,就会出现章一种的问题了,如果析构中抛出了异常怎么办?

我们可以用两种方法来解决:

方法1:

DBC::~DBC() {      try {(db.close();) }  //检查异常       catch (...) {            std::abort();      //如果catch到了异常,那么直接强迫结束程序      }}

 

方法2:

DBC::~DBC() {      try {(db.close();) }  //检查异常       catch (...) {            ... //如果catch到了异常,记录对close调用失败      }}

 

上面两种方法似乎都会异常进行了"提示",但是都无法针对“导致异常”的情况作出处理。

因此,我们可以考虑重新设计DBC类:

class DBC {public :     ....     void close() {          db.close();          closed = true;     }     ~DBC() {       // 确保每次调析构的时候都会关闭连接                   if (!closed) {               try {db.close();}               catch(...) {                    ...// 记录异常               }          }    }private:     DB db;     bool closed;}

 

 

■总结:

1.析构函数绝对不要吐出异常。如果一个被析构函数调用的函数可能抛出异常,析构函数应该要能捕捉任何异常,然后“吞下异常”或者终止程序。

2.如果需要对某个操作函数运行期间抛出的异常作出反应,那么class应该提供一个普通函数(而不是在析构函数中)执行该操作。

 

转载于:https://www.cnblogs.com/hustcser/p/4090217.html

你可能感兴趣的文章
程序中提醒用户进去App Store 评分 跳转 代码
查看>>
js闭包
查看>>
关于FlasCC(Adobe Flash C/C++ Compiler)
查看>>
学习网站搜集
查看>>
深度搜索(2)
查看>>
yum安装时出现"Existing lock /var/run/yum.pid: another copy is running as pid..."
查看>>
带抽象方法的枚举类
查看>>
推送通知(一)本地通知
查看>>
Python_初识函数和返回值_22
查看>>
大数据 电信客服项目
查看>>
软件工程迭代开发第二天
查看>>
创建简单的ajax对象
查看>>
LBS推荐系统的设计方法
查看>>
Java学习笔记(二十)——Java 散列表_算法内容
查看>>
Python开发【第十四篇】:Web框架本质
查看>>
【40】类中类
查看>>
第三章 springboot+swagger
查看>>
dwr.xml配置详解
查看>>
notepad++插件使用说明
查看>>
iOS 下拉通知让游戏继续
查看>>