Some day before I faced this question in a interview. So just guide me.
How to clean initialized resources if exception thrown from constructor in c++?
The trick is to use RAII(resource acquisition is initialization) to manage resources.
If you have pointer members then use smart pointers instead of raw pointers which will automagically do the cleanup job once a exception is thrown from constructor.
Good Read:
Herb Sutter's excellent GotW article "Construction Failures"
When an exception is thrown the stack is unrolled up to the catch point. As a consequence everything had been constructed in it is destroyed.
The point is, so, wrap every sensible resource into a class whose destructor takes care of the disposing of the associated resource.
If the resource is an heap allocated object, smart pointers do exactly that (delete the pointed object upon thair destruction), if the resource is an open file a stream closes it upon destruction. Everything else requires a custom wrapper.
But note the many "resources" are represented by handlers that are themselve void*. This enables to use smart poitner as well, by initializing then with the allocated resoure and specifying a deleting function.
What the technique plays better is much more a matter of taste and opportunity.
The best way to do it is: Allocate any resources in the constructors and deallocate any in the destructors.
Templates in C++ are very helpful for this purpose as we can make object creation atomic.
Use data members that free the resources when they are destroyed (aka RAII).
For example:
struct TwoStrings {
std::string string1;
std::string string2;
TwoStrings(const std::string &input) : string1(input) {
if (!input[1] == ':') {
throw std::logic_error('not a Windows absolute path');
// yes, absolute paths can begin \\, this is a toy example
}
if (input.back() == '\\') {
string2 = input;
} else {
string2 = input + "\\";
}
}
};
If the constructor throws (either logic_error
or bad_alloc
), then the already-initialized data member string1
is destroyed, freeing the resource. For that matter string2
is also destroyed, but if the constructor throws then string2
must still be empty, so that has no particular effect.
string
is an example of a class that manages resources, but there are many others. The most flexible of them are called "smart pointers", and can be configured to manage pretty much any resource, not just self-allocated arrays of characters like string
does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With