析构函数C ++中的异常 [英] Exception in Destructor C++

查看:142
本文介绍了析构函数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.

实时大肠杆菌示例

其他信息:

StackOverflow:将异常抛出析构函数

请注意,在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆