C++从析构函数抛出异常
这不是从析构函数抛出异常是否安全的问题。
http://www.parashift.com/c++-faq-lite /exceptions.html#faq-17.9 状态:
“在堆栈展开期间,所有这些堆栈帧中的所有本地对象都会被破坏。如果这些析构函数之一抛出异常(假设它抛出一个 Bar对象),C++ 运行时系统处于双输的境地:它是否应该忽略 Bar 并最终进入 } catch (Foo e) { 它最初的位置?它是否应该忽略 Foo 并寻找 } catch ( Bar e) { handler? 没有好的答案——任何一个选择都会丢失信息。”
IE:如果在堆栈展开期间引发另一个异常,则运行时系统将处于双赢的情况,因为“查找”的 catch 处理程序不明确。
当堆栈展开本身引发的异常位于 try/catch 块中时,上述情况是否存在“异常”?在这种情况下,没有歧义:
#include <iostream>
using namespace std;
class Component
{
public:
~Component()
{
cout << "In component destructor" << endl;
try
{
throw 1;
}
catch (...)
{
cout << "Caught exception in component destructor" << endl;
}
}
};
class Container
{
public:
~Container()
{
cout << "In container destructor" << endl;
Component component;
}
}
;
int main()
{
try
{
Container cont;
throw 'a';
}
catch (...)
{
cout << "Caught main exception ok" << endl;
}
return 0;
}
以下暗示了这一点,但我想知道是否有人知道相关的 C++ 标准部分。
“如果在堆栈展开期间析构函数抛出异常并且未处理该异常,则调用 Terminate() 函数。以下示例演示了这一点:”
This isn't a question on whether it's safe to throw an exception from a destructor.
http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.9 states:
"During stack unwinding, all the local objects in all those stack frames are destructed. If one of those destructors throws an exception (say it throws a Bar object), the C++ runtime system is in a no-win situation: should it ignore the Bar and end up in the } catch (Foo e) { where it was originally headed? Should it ignore the Foo and look for a } catch (Bar e) { handler? There is no good answer — either choice loses information."
IE: if during stack unwinding another exception is thrown, then the runtime system is in a no-win situation because the catch handler to 'look for' is ambiguous.
Is there an 'exception' to the above, when the exception that is thrown during stack unwinding itself is in a try/catch block? In this case there is no ambiguity:
#include <iostream>
using namespace std;
class Component
{
public:
~Component()
{
cout << "In component destructor" << endl;
try
{
throw 1;
}
catch (...)
{
cout << "Caught exception in component destructor" << endl;
}
}
};
class Container
{
public:
~Container()
{
cout << "In container destructor" << endl;
Component component;
}
}
;
int main()
{
try
{
Container cont;
throw 'a';
}
catch (...)
{
cout << "Caught main exception ok" << endl;
}
return 0;
}
The following implies it, but I was wondering if anyone knew of the relevant C++ standard sections.
"If during stack unwinding a destructor throws an exception and that exception is not handled, the terminate() function is called. The following example demonstrates this:"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的组件析构函数是安全的。您引用的规则仅适用于从析构函数(即析构函数的调用者)抛出异常
的情况。编辑:这是来自 标准(强调已添加)
Your Component destructor is safe. The rule you're quoting only applies if the exception is thrown out of the destructor (i.e., to the destructor's caller.)
EDIT: Here's one relevant quote from the standard (emphasis added)