异常处理,C++中的意外终止符
下面的代码是关于异常处理的。我得到了输出:异常处理,C++中的意外终止符,c++,exception,terminate,C++,Exception,Terminate,下面的代码是关于异常处理的。我得到了输出: Botch::f() I'll be back! 为什么水果没有被抓到?谢谢 忽略这一点。我想我已经提供了足够的细节 #include <exception> #include <iostream> using namespace std; void terminator() { cout << "I'll be back!" << endl; exit(0); } void (*o
Botch::f()
I'll be back!
为什么水果没有被抓到?谢谢
忽略这一点。我想我已经提供了足够的细节
#include <exception>
#include <iostream>
using namespace std;
void terminator() {
cout << "I'll be back!" << endl;
exit(0);
}
void (*old_terminate)() = set_terminate(terminator);
class Fruit {};
class Botch {
public:
void f() throw(Fruit, bad_exception) {
cout << "Botch::f()" << endl;
throw Fruit();
}
~Botch() { throw 'c'; }
};
int main() {
try{
Botch b;
b.f();
} catch(Fruit&) {
cout << "inside catch(Fruit)" << endl;
} catch(bad_exception&) {
cout << "caught a bad_excpetionfrom f" << endl;
}
}
因为在水果异常的堆栈展开过程中,您从Botch析构函数抛出了另一个异常。所以你的终结者被叫来了。这就是为什么从析构函数抛出异常是个坏主意,因为在果异常的堆栈展开过程中,您从拙劣的析构函数抛出了另一个异常。所以你的终结者被叫来了。这就是为什么从析构函数抛出异常是个坏主意,水果不会被捕获,因为代码永远不会到达catch子句。在main中的try块中,对b.f的调用抛出类型为Fruit的异常。作为响应,代码在输入catch子句之前销毁Botch对象。Botch的析构函数引发另一个异常,该异常触发调用终止。未捕获水果,因为代码从未到达该catch子句。在main中的try块中,对b.f的调用抛出类型为Fruit的异常。作为响应,代码在输入catch子句之前销毁Botch对象。Botch的析构函数抛出另一个异常,该异常触发调用终止。在main中调用b.f时,抛出一个水果。然后执行离开try块,在任何catch处理程序能够捕获该结果之前,b被销毁,并抛出“c”。在水果仍然处于活动状态时引发第二个异常将导致终止,而不管是否有任何捕获处理程序。 这就是为什么你永远不能从析构函数中抛出的原因。当在main中调用b.f时,会抛出一个水果。然后执行离开try块,在任何catch处理程序能够捕获该结果之前,b被销毁,并抛出“c”。在水果仍然处于活动状态时引发第二个异常将导致终止,而不管是否有任何捕获处理程序。
这就是为什么您永远不能从析构函数中抛出的原因。因为程序流程如下所示:
try{
Botch b;
b.f();
//-> exception of class Fruit has been thrown
//-> Stack unwinding: during stack unwinding object b,
//which is on stack is destroyed, and its destructor is called
//-> this destructor ~Botch() { throw 'c'; } throws another exception
//and this caused call of your terminator()
} catch(Fruit&) { // so we are never here
因为程序流程如下所示:
try{
Botch b;
b.f();
//-> exception of class Fruit has been thrown
//-> Stack unwinding: during stack unwinding object b,
//which is on stack is destroyed, and its destructor is called
//-> this destructor ~Botch() { throw 'c'; } throws another exception
//and this caused call of your terminator()
} catch(Fruit&) { // so we are never here