析构函数C ++中的异常 [英] Exception in Destructor C++
问题描述
我很清楚一个事实,即不应在析构函数中抛出任何异常。
I am well aware of the fact that one should not throw any exception in destructor.
但是,为了牢牢抓住这个概念,我编写了这个代码例如:-
But as a part of making my grip on this concept,I coded this example :-
#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;
}
}
根据我的理解,该程序应以调用std :: terminate(),因为同时会有两个异常。但是,该程序给出以下输出:-
As per my understanding, this program should be terminated by calling std::terminate() as there will be two exceptions at the same time. But, this program is giving the following output:-
30
exception caught
有人可以向我解释为什么这没有终止的逻辑吗?
Can anyone please explain me the logic behind this as to why this is not terminating?
推荐答案
std :: terminate
将在堆栈退卷期间引发异常时调用。这意味着如果在处理另一个异常的同时调用一个异常,则将调用 std :: terminate
。
std::terminate
will be called if an exception is thrown during stack unwinding. That means that if an exception is called while another exception is being handled, then std::terminate
will be called.
在您的示例中,这不会发生- A();
将构造并立即销毁一个实例 A
。然后会正确捕获抛出30
。
In your example, that doesn't happen - A();
will construct and immediately destroy an instance of A
. The throw 30
will then be caught correctly.
将代码更改为:
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;
}
}
将保证 std: :terminate
将被调用。在这种情况下, a
将被销毁并在处理另一个异常时抛出。
will guarantee that std::terminate
will be called. In this case, a
will be destroyed and will throw while another exception is being handled.
其他信息:
请注意,在C ++ 11及更高版本中, ,您的代码段将调用 std :: terminate
并向您提供警告:
Note that in C++11 and above, your code snippet will call std::terminate
and provide you a warning:
main.cpp:在析构函数'A ::〜A()':
main.cpp: In destructor ‘A::~A()’:
main.cpp:16:15:警告:throw将始终调用Terminate()
[- Wterminate]
main.cpp:16:15: warning: throw will always call terminate() [-Wterminate]
throw 30;
^~
main.cpp:16:15:注意:<在C ++ 11析构函数中,strong>默认为noexcept
main.cpp:16:15: note: in C++11 destructors default to noexcept
在抛出'int'实例后调用终止
terminate called after throwing an instance of 'int'
bash:第7行:1505中止(核心转储)./a.out
bash: line 7: 1505 Aborted (core dumped) ./a.out
如编译器输出所示,因为C ++ 11 析构函数隐式地 noexcept(true)
。如果要防止此行为,只需将它们标记为 noexcept(false)
。示例:
As seen in the compiler output, since C++11 destructors are implicitly noexcept(true)
. If you want to prevent this behavior, you can simply mark them as noexcept(false)
. Example:
~A() noexcept(false)
{
throw 30;
}
这篇关于析构函数C ++中的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!