EffectiveC++学习笔记-条款8

来源:互联网 发布:简明python教程3.0 编辑:程序博客网 时间:2024/05/07 22:20

条款8 别让异常逃离析构函数

析构函数绝对不能吐出异常

C++不禁止析构函数抛出异常。
例如一个负责连接数据库的class

class DBConnection{public:    ...    static DBConnection create();    void close();  //关闭连接 失败则会抛出异常}

为了确保使用者不忘记在DBConnection上调用close,可以在析构函数中调用。设计一个资源管理的class。

class DBConn{public:    ...    ~DBConn()    //确保数据库关闭了    {        db.close();    }private:    DBConnection db;}

所以可以允许这样使用。

DBConn dbc(DBConnection::create());

但是如果close调用出现了异常,DBConn的析构函数则会传播这个异常。

有两个方法可以避免这个问题。

  • 若close抛出异常就结束程序。
DBConn::~DBConn(){    try{ db.close(); }    catch(...)    {        //记录异常        std::abort();  //直接终止程序运行    }}
  • 或者直接吞掉异常
DBConn::~DBConn(){    try{ db.close(); }    catch(...)    {        //记录异常    }}

异常处理应该在普通函数中

一个比较好好的设计,就是重新设计DB接口,让客户有机会对可能出现的问题作出反应。

class DBConn{public:    ...    void close()    {        db.close();        closed = true;    }    ~DBConn()    {        if(!closed)        {            try{                db.close();            }            catch(...)            {                //制作运行记录,记录close调用失败            }        }    }private:    DBConnection db;    bool closed;};

这样把close的任务交给了客户,析构函数只是一个双保险。

原创粉丝点击