Pregunta

C++

I want a class to throw an exception before its constructor's body's opening curly brace { by using its own member function to prevent construction. I defined a member function, whose purpose is only to unconditionally throw an exception, with an arbitrarily chosen non-void return type and a dummy data member whose type matches that return type, so that I can trigger the throw by constructing this data member with a call to said member function in the constructor initializer list. This works but isn’t elegant because in a non-toy class, the dummy variable would serve no other purpose but to have an excuse for the member function to run, and the member function’s non-void return type serves no other purpose but to have an excuse for it to be callable by the constructor of the dummy data member of the same type.

This toy compiles but isn’t elegant:

class Toy
{
public:
    Toy() : dummy(preventer()) {}
private:
    int dummy;
    int preventer() {throw -1; return 0;}
};

#include <iostream>

int main()
{
    try
    {
        Toy t;
    }
    catch (const int& e)
    {
        std::cout << "caught the exception\n";
    }
    return 0;
}

Console Output:

caught the exception

Without the dummy variable, is there a way to throw an exception before the opening curly brace { of the constructor body?

¿Fue útil?

Solución 2

You can avoid the dummy return value of the function like this:

bool called = (function(), true);

The comma-operator in between the two expressions on the right evaluates the expressions in turn, discarding all but the last's result. What I'm wondering though is why you insist on doing that before the opening curly braces. What exactly are you trying to achieve here that you can't achieve with a call to the function as first thing in the body?

Note that if you want to abort as early as possible, doing that in a separate baseclass (you can use private inheritance there) is probably the best solution. It's the only solution that allows you to prevent even the construction of other bases, which your solution doesn't.

Otros consejos

Yes you can use a base class instead of a data member, and then invoking the base class' constructor.

Note that old versions of the GNU debugger gdb (some years ago) was unable to break on such exception.

However, works OK with Visual C++, and I believe also with modern versions of the GNU toolchain.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top