美文网首页
Effective c++ 学习笔记(item8)

Effective c++ 学习笔记(item8)

作者: 懒生活 | 来源:发表于2021-09-22 21:25 被阅读0次

    Effective c++ 学习笔记(item8)

    item8: prevent exceptions from leaving destructors.

    1 为什么不能在析构函数中抛出异常

    这里理解的关键是要意识当当c++正在处理异常的时候,突然又来了个"不受控制的"异常,会导致c++程序发生不可预料的问题。"不受控制"代表什么含义通过下面的例子描述。
    当c++处理异常的时候,c++会暂停程序的运行,开始逆着调用顺序逐层查找异常的catch函数。如果在当前函数中没有找到catch函数,那么需要把当前函数的资源释放(包括局部对象的销毁),然后转到更上一层去查找crath函数。找到后执行,然后代码从相关联的最后一个catch块后面的语句开始继续。如果一直没有找到,程序就会直接终止。这里隐藏的问题场景是,当处理中断时,发现本层内没有catch函数,然后释放本层内的局部对象,万一某个局部对象在释放(调用他的析构函数)时又抛出了异常,且这个异常并没有被析构函数自己处理(就是所谓的不受控制)这时就导致了异常处理时又撞见异常的局面,c++就无能为力了。如果析构函数抛出的异常被自己"处理掉既吞下", 那就不会有冲突。
    通过下面的例子可以很好的理解这个问题

    class ExceptionObj
    {
    public:
    ~ExceptionObj()
    {
    throw 1;
    }
    }
    int test()
    {
    ExceptionObj aExcption;
    throw 2; //在这里抛出的异常没有找到异常处理函数,所以
    //会退出该函数,并释放局部变量aExcption.
    //调用aExcption的析构函数时,析构函数又抛出了异常,且这个异常没有被处理
    //逃出了析构函数和当前的异常一起竞争使用异常的追溯能力。这样子程序就崩溃了
    }
    int main()
    {
    try
    {
    test();
    }
    catch (int e)
    {
    cout<<"exception "<<e<<endl;
    }
    cout<<"continue"<<endl;
    return 0;
    }
    

    如果把析构函数中的异常自己吞下,就不会有竞争导致程序崩溃,改写如下

    ~ExceptionObj()
    {
        try
    {throw 1;}
    catch(int e)
    {cout<<"swallow my own exception"<<endl;}
    }
    

    2 如果析构函数不可避免要抛出异常怎么办

    在析构函数中捕获并处理该异常。不要让异常跑出析构函数。 紧接着这个话题,Scott介绍了一个编程技巧。如果析构函数中会抛出异常,那么把抛出异常的部分提炼成public函数,让用户可以调用,这样子用户可以第一时间处理异常。但是为了避免用户意外漏了调用,在析构函数中还是要继续调用这部分可能抛异常的代码,同时要保证捕获。
    比如下面的代码

    DBConn::~DBConn()
    {
        try {db.close()}
        catch(...){}
    }
    

    一个数据库连接对象DBConn在析构的时候,希望能够自动关闭连接,但关闭连接的时候可能会抛出异常。上面在析构函数内部捕获异常的实现毫无疑问是正确的。但更好的是可以提供一个接口,让用户自己去调用,并让用户自己意识到要处理可能抛出的异常。而用户如果忘记了调用和处理异常,我们通过保留的析构函数上的关闭实现,实现双保险。示意代码如下

    DBConn::mannualClose()
    {db.close(); isClosed = true;}
    
    DBConn::~DBConn()
    {
        if(isClosed == false)
        {
            try {db.close()}
            catch(...){}
        }
    }
    

    相关文章

      网友评论

          本文标题:Effective c++ 学习笔记(item8)

          本文链接:https://www.haomeiwen.com/subject/heiggltx.html