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?
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.