在互联网上寻找C++脑筋急转弯,我发现了这个例子:
#include <iostream>
using namespace std;
class A {
public:
A()
{
cout << "A::A()" << endl;
}
~A()
{
cout << "A::~A()" << endl;
throw "A::exception";
}
};
class B {
public:
B()
{
cout << "B::B()" << endl;
throw "B::exception"; // <- crashes here
}
~B()
{
cout << "B::~B()";
}
};
int main(int, char**) {
try
{
cout << "Entering try...catch block" << endl;
A objectA;
B objectB;
cout << "Exiting try...catch block" << endl;
}
catch (const char* ex)
{
cout << ex << endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这就是我认为该程序会做的事情:
但是,当我运行该程序时,它实际上在标有< - 的行上崩溃了.有人可以解释那时到底发生了什么吗?
Tad*_*pec 11
如果你真的在编码,那么不仅仅是脑筋急转弯 从不会从析构函数中抛出异常.如果在堆栈展开期间抛出异常,terminate()则调用.在你的情况下,在处理B的构造函数中抛出的异常时抛出了A的析构函数.
编辑:更准确(如评论中所建议) - 永远不要让异常逃避析构函数.析构函数中捕获的异常没有问题.但是如果在堆栈展开程序期间必须处理两个异常 - 导致堆栈展开的异常和在展开期间转义析构函数的异常,std::terminate()那就去了.
当B::B()抛出一个异常堆栈展开开始.A::~A()被调用并抛出另一个未被捕获的异常A::~A().
如果正在进行堆栈展开时另一个异常会离开析构函数,则会调用terminate()并且看起来像程序崩溃.