1

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

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

4 回答 4

3

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

于 2013-04-16T13:11:54.583 回答
2

Fruit没有被捕获,因为代码永远不会到达那个 catch 子句。在try块中main,调用会b.f()引发类型异常FruitBotch作为响应,代码在进入 catch 子句之前销毁对象。的析构函数Botch抛出另一个异常,并触发对terminate.

于 2013-04-16T13:12:21.840 回答
0

b.f()main 中调用时,Fruit抛出 a。然后执行离开该try块,并且在任何 catch 处理程序可以捕获它之前Fruitb被销毁并被'c'抛出。在仍然活动的情况下抛出第二个异常Fruit会导致终止,无论任何捕获处理程序如何。
这就是为什么你永远不会从析构函数中抛出的原因。

于 2013-04-16T13:14:09.357 回答
0

因为程序流程如下:

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
于 2013-04-16T13:22:22.413 回答