【发布时间】:2014-07-06 11:29:29
【问题描述】:
据我了解,RAII是指在ctor中获取资源并在dtor中释放。
Ctor 获取了一些资源并且可能会失败,从而导致异常。 Dtor 释放资源也可能失败,但来自 dtor 的异常是 foobar 所以也不例外。
class A {
A() throw(Ex) { // acquire resources }
~A() throw() { // release resources }
}
因此,如果应该让 A 类的用户意识到 A 的未初始化中发生的错误,我可以将未初始化外包给一个抛出的函数,该函数从一个吞下异常的 dtor 调用:
class A {
A() throw(Ex) { // acquire resources }
~A() throw() { try {Release(); } catch(...) {} }
void Release() throw(Ex) { // release resources }
}
这样,如果用户想要发布错误的反馈,用户可以调用 Exit(),或者在 A 超出范围时让 dtor 完成它的工作而忽略(例如,在使用 A 的地方会发生一些其他异常)。
为了防止多次执行 Exit()(首先从用户显式执行,然后由 dtor 间接执行),我必须添加一个 init-status:
class A {
bool init;
A() throw(Ex) { init = true; // acquire resources }
~A() throw() { try {Release(); } catch(...) {} }
void Release() throw(Ex) {
if(!init) return;
init = false;
// release resources
}
}
有没有更好的方法来做到这一点,或者我是否必须在每次资源释放失败并且我想知道它时实现该模式?
【问题讨论】:
-
根据经验:不要从析构函数中抛出异常!
-
结果是RAII不处理发布过程中的错误。因此,您应该为非抛出版本选择一个合理的默认行为,并在需要时添加一个明确的错误处理机制。
std::fstream这样做。 -
除了指定一个函数不抛出外,您是否不使用异常规范(这可能会使用
noexcept或noexcept(true))。 -
在这种情况下,对于 RAII,错误处理机制总是必须放在类本身而不是使用它的地方?
-
我知道编译器忽略了 throw(Ex) 子句,它只是为了解释类的行为
标签: c++ exception destructor raii