2013-06-27 3 views
3

C++ Рассмотрим ниже код:Понимание 'попробовать':

#include <iostream> 
#include <stdexcept> 

class E{ 
    public: 
     E(int n):m_n(n) 
    { 
     if (0>n) 
     { 
      throw std::logic_error("5"); 
     } 
    } 
     ~E(){cout << m_n << "#" <<endl;} 
    public : 
     int m_n; 
}; 

int main() 
{ 
    try{ 
     E a(5); 
     try{ 
      E c(7); 
      E b(-8); 
      E d(9); 
     } 
     catch(const std::exception &e) 
     { 
      cout <<2 <<"&&&"<<e.what()<<endl; 
      throw e; 
     } 
    } 
    catch(const std::exception &e) 
    { 
     cout <<3 << "^^^^^ "<<e.what() << endl; 
     throw e; 
    } 
    return 0; 
} 

Выход меня есть:

7# 
2&&&5 
5# 
3^^^^^ St9exception 
std::exception: St9exception 
Aborted. 

Может кто-нибудь, пожалуйста, объясните, почему такой вывод? Я ожидаю, что первые 5 # будут отображаться.

+4

Отметьте код, и вы увидите его почти мгновенно. – StoryTeller

+2

Орден разрушения - это противоположность творения. – PlasmaHH

+0

Почему SO избавился от «слишком локализованного» закрытого голосования? Кажется, здесь несколько уместно – stijn

ответ

5

Вот рабочий процесс вашей программы в псевдокоде:

{ 
    //outer try 
    create e(5); 
    { 
    //inner try 
    create e(7); 
    failed create e(-8);//exception here 
    throw; 
    delete e(7);//-> 7# 
    } 
    { 
    //catch in inner try; 
    cout &&&;//-> 2&&&5 
    throw e; // throw sliced copy of original exception 
    } 
    delete e(5);//-> 5# 
} 
{ 
    //catch in outer try 
    cout ^^^^;//-> 3^^^^^ St9exception (the last thrown is pure std::exception) 
    throw e; // throw another copy, no more slicing as it's already exception 
} 
program termination because of uncaught exception; 
//-> std::exception: St9exception 
//-> Aborted. 

//return 0; was never reached 
0

Поскольку строительство b терпит неудачу, это приводит к тому, уже существующие c быть уничтожены, то внутренняя задвижка должна быть выполнена.

Поскольку он повторно бросает, то уже существующий a во внешней попытке уничтожается и выполняется внешний захват.

С тех пор, как он повторно запускается снова, и больше нет улова, исключение исключается из main(), где оно обрабатывается библиотекой поддержки, которая печатает сообщение и прерывается.

Порядок уничтожения - это обратная сторона конструкции. Итак, c, который строится после a, уничтожен раньше.

b, и d, никогда не вступали в жизнь.

0

#5 будет отображаться, когда a будет уничтожен. Это произойдет после того, как c будет уничтожен, что произойдет в stack unwinding после того, как вы указали e.what().