Q015#
#include <iostream>
#include <exception>
int x = 0;
class A {
public:
A() {
std::cout << 'a';
if (x++ == 0) {
throw std::exception();
}
}
~A() {
std::cout << 'A';
}
};
class B {
public:
B() {
std::cout << 'b';
}
~B() {
std::cout << 'B';
}
A a;
};
void foo() {
static B b;
}
int main() {
try {
foo();
} catch (std::exception &) {
std::cout << 'c';
foo();
}
}
Answer#
click to see answer
acabBAExplain#
在 try 中调用 foo() 函数,该函数中定义了一个局部静态变量 b。在构造 b 对象时,会先构造 B 类的成员变量 a,a 调用 A 对象的默认构造函数,输出 a,然后对 x 进行判断,因为是后置 ++(先使用后增加),所以判断时 x == 0,执行抛出异常的操作 throw exception(),catch (std::exception &) 捕获到该异常后输出 c,并调用 foo() 函数,进入 foo() 函数,因为在 try 中执行该函数时,局部静态变量 b 并未完成初始化,所以将再次对 b 进行初始化,先构造 B 类成员变量 a,调用 A 对象默认构造函数,输出 a,然后对 x 进行判断,当前 x != 0,所以不执行抛出异常的操作,成员变量 a 构造完成,开始调用 B 的默认构造函数,输出 b,在程序终止后,局部静态变量 b 开始析构,先调用 b 的析构函数,输出 B,再调用成员变量 a 析构函数,输出 A。
构造函数中抛出异常,可能会使对象部分构造,随之就有可能导致资源泄漏或不一致的对象状态,所以应避免在构造函数中抛出异常