ami*_*ngh 36 c++ destructor exception-handling
我很清楚,不应该在析构函数中抛出任何异常.
但作为掌握这一概念的一部分,我编写了这个例子: -
#include <iostream>
using namespace std;
class A {
private:
int i;
public:
A()
{
i = 10;
}
~A()
{
throw 30;
}
};
int main(){
try{
A();
throw 10;
}
catch (int i){
cout << i << endl;
cout << "exception caught" << endl;
}
}
Run Code Online (Sandbox Code Playgroud)
根据我的理解,这个程序应该通过调用std :: terminate()来终止,因为同时会有两个例外.但是,这个程序给出了以下输出: -
30
exception caught
Run Code Online (Sandbox Code Playgroud)
任何人都可以向我解释这背后的逻辑,为什么这不是终止?
Vit*_*meo 63
std::terminate如果在堆栈展开期间抛出异常,将调用它.这意味着,如果一个异常被称为而另一个异常被处理,那么std::terminate就会被调用.
在你的例子中,这不会发生 - A();将构造并立即销毁一个实例A.在throw 30将被正确地捕获.
将代码更改为:
int main(){
try{
A a; // begin `a` lifetime
throw 10; // | throw #0
// | end `a` lifetime
// throw #1
}
catch(int i){
cout<<i<<endl;
cout<<"exception caught"<<endl;
}
}
Run Code Online (Sandbox Code Playgroud)
将保证std::terminate将被召唤.在这种情况下,a将被销毁并将在处理另一个异常时抛出.
附加信息:
请注意,在C++ 11及更高版本中,您的代码段将调用std::terminate并提供警告:
main.cpp:在析构函数'A :: ~A()'中:
main.cpp:16:15:警告:throw将始终调用terminate()[ - Wminminate]
Run Code Online (Sandbox Code Playgroud)throw 30; ^~main.cpp:16:15:注意:在C++ 11中,析构函数默认为noexcept
抛出'int'实例后调用terminate
bash:第7行:1505 Aborted(core dumped)./a.out
如编译器输出中所示,因为C++ 11 析构函数是隐式的noexcept(true).如果要阻止此行为,可以将其标记为noexcept(false).例:
~A() noexcept(false)
{
throw 30;
}
Run Code Online (Sandbox Code Playgroud)