I have a class whose constructor may throw an exception. Here’s some code that will catch the exception:
try {
MyClass instance(3, 4, 5);
}
catch (MyClassException& ex) {
cerr << "There was an error creating the MyClass." << endl;
return 1;
}
But of course no code after the try/catch can see instance
because it’s now out of scope. One way to resolve this would be to declare and define instance
separately:
MyClass instance;
try {
MyClass instance(3, 4, 5);
}
...
except that my class doesn’t have the appropriate zero-argument constructor. In fact, this case right here is the only one in which such a constructor would even make sense: the MyClass
object is intended to be immutable, in the sense that none of its data members change after construction. If I were to add a zero-argument constructor I’d need to introduce some instance variable like is_initialized_
and then have every method check to make sure that that variable is true
before proceeding. That seems like far too much verbosity for such a simple pattern.
What is the idiomatic way to deal with this kind of thing? Do I need to suck it up and allow instances of my class to be declared before they’re initialized?
Dynamically allocate the instance using
new
:You could use a generic helper function that catches exceptions and the future
std::optional
(orboost::optional
) to signal the successful or failed creation of the instance:Using basically this:
Where
instance
is now anoptional<MyClass>
. To test the result and separate availablity of the instance from the error case is also simple:Of course the exception information will be lost this way, but you could go for a less generic function and add some logging in the catch-block depending on your needs.
You should be doing everything you need to do inside the
try
block:After all, it is only within the
try
block thatinstance
has been successfully created and so can be used.I do wonder whether your
catch
block is really handling the exception. If you can't do anything to resolve the situation, you should be letting it propagate.