banner
cells

cells

为美好的世界献上 bug

Q015-关于构造函数抛出异常

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 acabBA

Explain#

try 中调用 foo() 函数,该函数中定义了一个局部静态变量 b。在构造 b 对象时,会先构造 B 类的成员变量 aa 调用 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

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

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。