【发布时间】:2018-11-29 10:37:45
【问题描述】:
我有以下代码:
#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;
}
现在,在陈述问题之前,我想指出这段代码是不好的做法(例如,从构造函数中抛出异常将导致对象没有被完全创建,因此不会调用析构函数,这可能会导致内存泄漏或其他问题)。
现在,主要的顺序是这样的:
正在打印
"Entering try...catch block"。调用
A的构造函数,打印"A::A()"调用
B的构造函数,打印"B::B()",并抛出异常。抛出异常,
"Exiting try...catch block"行不会被打印。块被退出,所以A的析构函数被调用。A的析构函数打印"A::~A()"并引发另一个异常。
第二个异常(在 5 中)导致 main 在进入 catch 块之前抛出异常。
我的问题是 - 有没有办法在不改变类 A,B 的情况下捕获主要的第二个异常?
我尝试用另一个 try-catch 块包围整个 try-catch 块和 catch 块内部,但没有成功。
谢谢。
【问题讨论】:
-
在堆栈展开时抛出析构函数会导致程序终止,抛出析构函数是一个非常不好的习惯
-
任何时候都只能有一个活动异常。
-
次要注意:在构造函数中抛出异常 - 通常 - 绝对没问题。
-
顺便说一句。从构造函数中抛出并不坏,它几乎是唯一表明构造出现问题的方法。但是,如果您使用原始指针,那么您应该注意它们。
-
只是一个练习,您可以使用内部
try {B objectB;} catch(...){}并分别捕获该异常。不过还是比较有用的。
标签: c++ exception exception-handling destructor constructor-exception