How to clear initialized resources if exception is thrown from constructor in C ++

The day before I came across this question in an interview. So just guide me.

How to clear initialized resources if an exception is thrown from a constructor in C ++?

+6
source share
4 answers

The trick is to use RAII (initialize resource collection) for resource management.

If you have pointer elements, use smart pointers instead of raw pointers, which will automatically execute the cleanup task after an exception is thrown from the exception constructor.

Good reading:
Herb Sutter GotW's excellent Construction Failure article

+6
source

Use data members that free resources when they are destroyed (aka RAII).

For instance:

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 element string1 destroyed, freeing the resource. In this case, string2 also destroyed, but if the constructor throws, then string2 should be empty, so it has no special 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 control almost any resource, and not just with self-distributed arrays of characters such as string .

+1
source

When an exception is thrown, the stack expands to the catch point. As a result, everything that was built in it was destroyed.

A point, therefore, transfers each intelligent resource to a class whose destructor takes care of disposing of the associated resource.

If the resource is a heap allocated, smart pointers do exactly that (delete a pointy object when killing the tai), if the resource is an open file, the thread closes it when killing. Everything else requires a special shell.

But note that many of the "resources" are represented by handlers, which are itselve void *. It also allows the use of an intelligent poitner, initializing then with the selected resoure and defining the delete function.

The fact that the technique plays better, much more depends on the taste and capabilities.

+1
source

The best way to do this: Allocate any resources in the constructors and free them in the destructors.

C ++ templates are very useful for this purpose, since we can make creating an object atomic.

+1
source

Source: https://habr.com/ru/post/926932/


All Articles