C++之不要让异常逃离析构函数(8)---《Effective C++》

来源:互联网 发布:小布老师linux 编辑:程序博客网 时间:2024/05/21 16:58

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

我们先来参看如下代码:

class A{public:    ...    ~A(){...}};void showA(){    std::vector<A> v;    ...}

考虑如下问题,当showA函数调用结束时,vector v这个局部变量需要被销毁,他讲负责销毁所有的A,加入v中有n个A,第一个A调用的时候发生异常,其他n-1个对象还是应该被销毁,如果n-1个对象中继续有对象在析构的时候发生异常,这两个异常同时存在的情况下,程序若不是结束执行就是导致不明确的行为,这显然不是我们想要的。
那么应该怎样解决这种问题呢?举个例子,看看如下代码:

class DatabaseCon{public:    static DatabaseCon create();    ...    void close();};class Con{public:    ...    ~Con(){        db.close();    }private:    DatabaseCon db;};

调用成功,当然是我们所期待的,调用失败呢,很可怕的是Con的析构函数会传播这个异常,即允许异常离开析构函数,造成内存泄露,资源泄露等一系列可怕的问题!
两个方法可以处理该问题:

1)程序抛出异常则直接结束程序,通常通过调用abort完成;

Con::~Con(){    try{db.close();}    catch(...)[        ...          //制作运转记录,记下对close的调用失败,这样可以将不明确行为提前扼杀掉        std::abort();    }

2)吞下函数抛出的异常;

Con::~Con(){    try{db.close();}    catch(...){        ...     //制作运转记录,记下close的调用失败}

总结如下:
1)析构函数绝对不要吐出异常,如果一个被析构函数调用的函数可能抛出异常,析构函数应该捕捉任何异常,然后吞下他们(不传播)或者结束程序;
2)如果客户需要对某个操作函数运行期间抛出的异常作出反隐,那么class至少应该提供一个普通函数执行该操作,而并不是在析构函数中执行该操作。

阅读全文
0 0
原创粉丝点击