关于 RAII,C++“尝试”/“捕获”块是否与其他块相同
Are C++ `try`/`catch` blocks the same as other blocks, regarding RAII?
好的,那么如果我使用 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(全局解释器锁)。
是的,它将完全按照您的要求执行:首先释放 RAII 资源,然后处理异常块。
"...如果我这样做,RAII 实例的工作方式是否相同:..."
当然会。如果抛出异常,RAII 实例将超出范围,析构函数将在catch
之前调用。
这也适用于任何更高的级别,如果您只是throw
并且没有任何try
/catch
块,则会调用您的函数。这就是所谓的堆栈展开。
是的
,这是在标准中指定的:
15.2 构造函数和析构函数 [除外]
2 为每个类类型的自动对象调用析构函数 自进入
try
块以来建造。自动对象 以与其完成相反的顺序销毁 建设。
相关文章:
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- MESI协议和std::atomic-它是否确保所有写入立即对其他线程可见?
- "std::list::splice(std::const_iterator pos, std::list&& other)"是否保证将"其他"留空?
- 是否可以使用其他变量为变量分配值,而无需在 C++ 中更改其值?
- 对于BTreeMap和其他依赖于Ord的东西,是否有等效于C++比较器对象?
- MOVNTI 存储是否相对于由同一线程创建的其他 MOVNTI 存储重新排序?
- 在C++单元测试上下文中,抽象基类是否应将其他抽象基类作为函数参数
- 这种比较是否不一致(或者存在其他问题)?
- 了解'this'或其他参数是否为右值
- 如何在 Linux 下使用 c++ 知道文件是否被其他进程使用?
- 严格的别名是否会阻止您通过其他类型写入 char 数组?
- C++如何判断互斥体在阻塞其他线程时是否被单个线程不成比例地占用
- 当其他线程正在编写线程安全时,我是否必须互斥读操作
- 检查IP是否在其他IP网络范围内,并查找下一个可用IP
- cv::cuda::setTo()是否有其他选择
- 如何知道指针是否已在其他地方释放
- 如何检查一个字符串是否包含多个其他字符串?
- 是否可以将多个结构作为一个数据包存储在一个函数中,然后传递给其他函数并在那里提取?
- 除了系统("pause")之外,是否有其他选项可以保持可执行文件打开?
- 在代码的其他部分中对lock_gard和不使用相同的互斥锁是否安全?