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。
构造函数中抛出异常,可能会使对象部分构造,随之就有可能导致资源泄漏或不一致的对象状态,所以应避免在构造函数中抛出异常