异常处理,c++中的意外终止符

exception handling, unexpected terminator in c++

本文关键字:意外 终止 c++ 异常处理      更新时间:2023-10-16

下面的代码是关于异常处理的。我得到了输出:

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;
    }
}

因为在Fruit异常的堆栈展开期间,你抛出了另一个异常(来自Botch析构函数)。所以你的终结者被叫来了。这就是为什么从析构函数抛出异常是一个坏主意,

Fruit未被捕获,因为代码从未到达该catch子句。在maintry块中,对b.f()的调用抛出了一个Fruit类型的异常。作为响应,代码在进入catch子句之前销毁Botch对象。Botch的析构函数抛出另一个异常,触发对terminate的调用。

在main中调用b.f()时,会抛出一个Fruit。然后执行离开try块,在任何catch处理程序捕获Fruit之前,b被销毁,'c'被抛出。当Fruit仍然处于活动状态时抛出第二个异常将导致终止,而不管是否有任何catch处理程序。
这就是为什么永远不能抛出析构函数

因为程序流程如下:

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