异常处理,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