关于RAII,C ++`try` /`catch`是否与其他块相同?

时间:2016-01-20 18:23:31

标签: c++ exception try-catch raii noexcept

好的,如果我使用RAII惯用语来管理某些上下文属性*,如果我在try块的开头裸体使用它,它是否会像我期望的那样工作?

换句话说,如果我有这个:

struct raii {
    raii() {
        std::cout << "Scope init"
                  << std::endl; }
    ~raii() {
        std::cout << "Scope exit"
                  << std::endl; }
};

......我成功地使用了它:

{
    raii do_the_raii_thing;
    stuff_expecting_raii_context();
    /* … */
}

...如果我这样做,RAII实例的工作方式是否相同:

try {
    raii do_the_raii_thing;
    stuff_expecting_raii_context_that_might_throw();
    /* … */
} catch (std::exception const&) {
    /* … */
}

这可能是一个愚蠢的问题,但我想在此检查自己的理智 - 我对noexcept保证的微妙之处以及其他与例外相关的细节感到模糊 - 请原谅我的天真

[*]对于那些好奇的人来说,这是我在RAII管理的Python C-API狡猾的GIL(全局解释器锁),在我的具体案例中

3 个答案:

答案 0 :(得分:5)

是的,它会完全符合您的要求:首先发布RAII资源,然后处理异常块。

答案 1 :(得分:3)

  

“......如果我这样做,RAII实例的工作方式是否相同:......”

当然可以。如果抛出异常, RAII实例将超出范围并在catch之前调用析构函数。

这也适用于任何较高级别,如果您只是throw并且没有任何try / catch块,则会调用您的函数。这叫做stack unwinding

答案 2 :(得分:2)

是的,这是在xlwings

中指定的
  

15.2构造函数和析构函数[except.ctor]

     

2为类类型的每个自动对象调用析构函数   自输入try块后构造。自动对象   以完成他们的相反顺序销毁   构造