2010-07-22 1 views
1

В следующем коде, каким образом деструкторы b, q и e вызываются и вызывается перед обработкой исключения. (The "соиЬ ..." части остатки первоначального вопроса)Захватывая параметр исключения по значению, каков порядок вызова деструкторов?

#include <iostream> 
using namespace std; 

class A { 
public: 
    A(int arg) : m(arg) { 
    cout << "A::A(int) " << m << endl; 
    m = 2*arg; 
    } 
    virtual void f() { 
    cout << "A::f() " << m << endl; 
    } 
    void g() { 
    cout << "A::g(A) " << m << endl; 
    } 

    int m; 
}; 

class B : public A { 
public: 
    B(int arg) : A(arg) { 
    cout << "B::B(int) " << m << endl; 
    m = 3*arg; 
    } 
    ~B() { 
    cout << "B::~B()" << endl; 
    } 
    void f() { 
    cout << "B::f(A&) " << m << endl; 
    } 
    virtual void g() { 
    B q(*this); 
    throw q; 
    cout << "B::g(A) " << m << endl; 
    } 
}; 

int main() { 
    try { 
    B b(1); 
    b.g(); 
    } catch (A e) { 
    cout << "Error: "; 
    e.f(); 
    } 
    return 0; 
} 

Если это возможно, могли бы вы объяснить причину. Спасибо.

+1

'b' никогда не имеет своего деструктора, потому что он никогда не удаляется. (то есть: вы просачиваетесь.) – GManNickG

+0

Я отредактировал код как статическое распределение. Спасибо. – hizki

+0

@hizki: Это фактически автоматическое распределение (распределение стека) теперь, а не статическое распределение. – GManNickG

ответ

1

q «s desctructor называют первым, так как он разрушается в первой части стека размотки (локальные объекты во внутреннем большинстве сферы разрушаются), затем b» ы вызывается деструктор, и как часть стека разматывания. Оба они уничтожаются до того, как блок catch даже введен. Развертывание стека происходит до выполнения обработчика исключений.

Имейте в виду, однако, что объекты исключения копируются так в B::g() копию (объект исключения) из q, который является копией b создается и ее жизни продолжается до конца блока улова. Он используется для инициализации (нарезки!) e.

Деструктор для самого объекта исключения (копия q) выполняется сразу же после e уничтожается (как обработчик не приводит к выходу через throw;). Это упорядочение указано в стандарте.

Смежные вопросы