Search code examples
c++exceptionconstructorraii

RAII approach to catching constructor exceptions


I have a class that can throw an exception in its constructor. How can I declare an instance of that class in a try/catch block, while still making it available in the right scope?

try { MyClass lMyObject; }
catch (const std::exception& e) { /* Handle constructor exception */ }

lMyObject.DoSomething(); // lMyObject not in scope!

Is there an alternative way to accomplish this, while respecting the RAII idiom?

I'd prefer not to use an init() method for two-phased construction. The only other thing I could come up with was:

MyClass* lMyObject;

try { lMyObject = new MyClass(); }
catch (const std::exception& e) { /* Handle constructor exception */ }

std::shared_ptr<MyClass> lMyObjectPtr(lMyObject);
lMyObjectPtr->DoSomething();

Works OK, but I'm not happy with the raw pointer in scope and pointer indirection. Is this just another C++ wart?


Solution

  • If a constructor throws that means the object failed to initialize and hence it failed to start its existence.

    MyClass* lMyObject;
    try { lMyObject = new MyClass(); }
    catch (std::exception e) { /* Handle constructor exception */ }
    

    In the above if the constructor throws an exception, lMyObject is left uninitialized, in other words, the pointer contains an indeterminate value.

    See classic Constructor Failures for a detailed explanation:

    We might summarize the C++ constructor model as follows:

    Either:

    (a) The constructor returns normally by reaching its end or a return statement, and the object exists.

    Or:

    (b) The constructor exits by emitting an exception, and the object not only does not now exist, but never existed.

    There are no other possibilities.