banner
cells

cells

为美好的世界献上 bug

Q015-About throwing exceptions in constructors

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#

When calling the foo() function within the try block, a local static variable b is defined in this function. When constructing the b object, the member variable a of class B is constructed first. a calls the default constructor of the A object, outputting a, then checks x, because it is post-increment (x++), the check is x == 0, performs the operation to throw an exception throw std::exception(). Upon catching the exception with catch (std::exception &), it outputs c, and calls the foo() function again. Inside the foo() function, since the function was called within the try block, the local static variable b has not been fully initialized, so it will be initialized again. It constructs the member variable a of class B, calls the default constructor of the A object, outputting a, then checks x, where x != 0, so it does not throw an exception. The construction of member variable a is completed, and it starts calling the default constructor of B, outputting b. After the program terminates, the local static variable b begins to be destructed, calling the destructor of b, outputting B, then calling the destructor of member variable a, outputting A.

Throwing exceptions in constructors may result in partially constructed objects, which can lead to resource leaks or inconsistent object states, so it should be avoided.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.