2012-07-20 128 views
12
class A{ 
    public: 
     A() { throw string("exception A"); }; 
}; 

class B{ 
    A a; 
    public: 
     B() try : a() {} catch(string& s) { cout << &s << " " << s << endl; }; 
}; 

int main(){  
    try{ 
     B b; 
    }catch(string& s){ 
     cout << &s << " " << s << endl; 
    } 
    return 0; 
} 

输出是:异常被捕获两次

0x32c88 exception A 
0x32c88 exception A 

由于异常已经陷入了B构造,为何仍然出现在主函数?

回答

21

当contol流到达构造函数的function-try-block的处理程序结束时,捕获的异常将自动重新抛出。

在派生类构造函数中构造基类或成员期间,您无法抑制抛出的异常,因为这会导致构造派生对象的基础或成员未能构建。

这GOTW是相关的:http://www.gotw.ca/gotw/066.htm

从ISO/IEC 14882:2011 15.3 [except.handle]/15:

如果控制到达处理程序结束当前处理的异常被重新抛出构造函数或析构函数的函数尝试块。 [...]