C++ -捕获双精度异常

2ekbmq32  于 2023-02-01  发布在  其他
关注(0)|答案(2)|浏览(141)

下面的代码:

#include <iostream>
using namespace std;

class A {
public:
    A()  { cout << "A::A()" << endl;}
    ~A() { cout << "A::~A()" << endl; throw "A::exception";}
};

class B {
public:
    B()  { cout << "B::B()" << endl; throw "B::exception";}
    ~B() { cout << "B::~B()";}
};

int main() {
    try {
        cout << "Entering try...catch block" << endl;
        A   objectA;
        B   objectB;
        cout << "Exiting try...catch block" << endl;
    } catch (char const * ex) {
        cout << ex << endl;
    }
    return 0;
}

现在,在陈述问题之前,我想指出这段代码是不好的做法(例如,从构造函数抛出异常将导致对象没有完全创建,因此析构函数将不会被调用,这可能导致内存泄漏或其他问题)。
现在,主要的顺序是:
1.正在打印"Entering try...catch block"
1.调用A的构造函数,打印"A::A()"
1.调用B的构造函数,打印"B::B()",抛出异常。
1.抛出异常,行"Exiting try...catch block" * 将不被打印 *。退出块,因此调用A的析构函数。

  1. A的析构函数打印"A::~A()"并抛出另一个异常。
    第二个异常(5中的)导致main在进入catch块之前抛出异常。
    我的问题是--有没有一种方法可以在不改变类AB的情况下捕获main中的第二个异常?
    我试过用另一个try-catch块包围整个try-catch块和catch块内部,但没有成功。
    谢谢。
aor9mmx1

aor9mmx11#

来自www.example.comcppreference.com:
和其他函数一样,析构函数可以通过抛出异常[...]终止,但是如果这个析构函数碰巧在栈展开过程中被调用,则会调用std::terminate
因此,尝试从~A()抛出异常不会导致抛出第二个异常;它将导致程序终止。如果需要"捕获"此"第二个异常",则需要干扰the termination handler。或者,您可以找到不在析构函数中引发异常的方法。继续www.example.comcppreference.com:
虽然std::uncaught_exception有时可以用来检测正在进行的堆栈展开,但允许任何析构函数通过抛出异常来终止通常被认为是不好的做法。

juud5qan

juud5qan2#

您可以使用set_terminate+longjmp来避免程序终止。

#include <iostream>
#include <setjmp.h>

using namespace std;

jmp_buf jmpBuf;

class A {
public:
    A()  { cout << "A::A()" << endl;}
    ~A() noexcept(false){ cout << "A::~A()" << endl; throw "A::exception";}
};

class B {
public:
    B()  { cout << "B::B()" << endl; throw "B::exception";}
    ~B() { cout << "B::~B()";}
};

int main() {

    set_terminate([](){
        cout<<"long jump begin" << endl;
        longjmp(jmpBuf,1);
    });

    if(setjmp(jmpBuf)==0) {

        try {
            cout << "Entering try...catch block" << endl;
            A objectA;
            B objectB;
            cout << "Exiting try...catch block" << endl;
        } catch (char const *ex) {
            cout << ex << endl;
        }
    }else{
        cout<<"long jump end" << endl;
    }
    return 0;
}

相关问题