好的,如果我使用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(全局解释器锁),在我的具体案例中
答案 0 :(得分:5)
是的,它会完全符合您的要求:首先发布RAII资源,然后处理异常块。
答案 1 :(得分:3)
“......如果我这样做,RAII实例的工作方式是否相同:......”
当然可以。如果抛出异常, RAII实例将超出范围并在catch
之前调用析构函数。
这也适用于任何较高级别,如果您只是throw
并且没有任何try
/ catch
块,则会调用您的函数。这叫做stack unwinding。
答案 2 :(得分:2)
是的,这是在xlwings:
中指定的15.2构造函数和析构函数[except.ctor]
2为类类型的每个自动对象调用析构函数 自输入
try
块后构造。自动对象 以完成他们的相反顺序销毁 构造