【问题标题】:Are C++ `try`/`catch` blocks the same as other blocks, regarding RAII?关于 RAII,C++ `try`/`catch` 块是否与其他块相同?
【发布时间】:2016-04-26 17:56:27
【问题描述】:

好的,所以如果我使用 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(全局解释器锁)

【问题讨论】:

  • 嗯,这听起来确实涉及异常(或者至少它可以) - 但我认为您指的是这个问题的解释:stackoverflow.com/q/161177/298171 ...是吗?
  • 糟糕,我回复的评论消失了!

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


【解决方案1】:

是的,它会做你想做的事:首先释放 RAII 资源,然后处理异常块。

【讨论】:

    【解决方案2】:

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

    他们肯定会的。如果抛出异常,RAII 实例 将超出范围并在catch 之前调用析构函数。

    这也适用于任何上层,如果您只是 throw 并且没有任何 try/catch 块,则调用您的函数。那叫stack unwinding

    【讨论】:

      【解决方案3】:

      是的,这是在Standard中指定的:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-19
        • 2013-07-08
        • 2018-08-25
        • 1970-01-01
        • 2011-01-23
        • 1970-01-01
        • 1970-01-01
        • 2010-09-29
        相关资源
        最近更新 更多