При отлове параметра исключения по значению, в каком порядке вызываются деструкторы? - PullRequest
1 голос
/ 23 июля 2010

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

#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 Ответ

1 голос
/ 23 июля 2010
Сначала вызывается дескриптор

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...