2013-04-16 1 views
1

Следующий код посвящен обработке исключений. Я получил выход:Обработка исключений, неожиданный терминатор в C++

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

ответ

2

Fruit не пойман, потому что код никогда не достигает этого положения catch. В блоке try в main, вызов b.f() исключает тип Fruit. В ответ код разрушает объект Botch перед вводом предложения catch. Деструктор Botch вызывает еще одно исключение и вызывает вызов terminate.

3

Потому что во время стека размотки за исключением Fruit вы бросили еще одно исключение (из Botch деструктора). Тогда вместо этого был вызван ваш терминатор. Вот почему бросание исключений из деструктора - плохая идея,

0

Когда вызывается b.f(), вызывается Fruit. Затем выполнение оставляет блок try, и до того, как любой уловщик может поймать, что Fruit, b уничтожен и брошено 'c'. Второе исключение, в то время как Fruit все еще активно, приводит к завершению независимо от любых обработчиков захвата.
Вот почему вы никогда не будете бросать из деструкторов.

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