开发者

When catching an exception's parameter by value, what is the order in which the destructors are called?

In the following code, what is the order in which the destructors of b, q and e are called, and which is called before handling the exception. (The "cout..." parts are leftover for the original question)

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

If it's possible, could you explain the reason. Thank you.


q's desctructor is called first because it is destroyed as the first part of stack unwinding (local objects in the inner most scope are destroyed first), then b's destructor is called, also as part of stack unwinding. Both are destroyed before the catch block is even entered. Stack unwinding happens before the exception handler is executed.

Bear in mind, though, that exception objects are copied so in B::g() a copy (the exception object) of q which is a copy of b is created and its lifetime extends to the end of the catch block. It is used to initialize (slicing!) e.

The destructor for the exception object itself (a copy of q) is executed immediately after e is destroyed (as the handler doesn't exit via a throw;). This ordering is specified in the standard.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜