Destructor exception

In my destructor, I need to clear some resources. Let me say that I have three challenges to clear the resources that could be thrown. Since this is not good in order to exclude the possibility of leaving the destructor, what should be my design template? Apparently, the method below does not scale.

Thanks.

class B::~B(){ try{ clearResourceA() } catch{ try{ clearResourceB(); } catch{ clearResourceC(); } clearResourceC(); } clearResourceB(); . . } 
+6
c ++
source share
6 answers

Why not:

 try{clearResourceA();} catch(...){} try{clearResourceB();} catch(...){} try{clearResourceC();} catch(...){} 
+10
source share

Encapsulate each resource in a class that clears them in its destructor (with the surrounding try / catch):

 struct ProperlyManagedA { // some means of using the resource - a rudimentary way is this: A &getA() { return a; } const A &getA() const { return a; } // cleanup ~ProperlyManagedA() { try { a.clear(); // whatever it is ClearResourceA actually does } catch (...) {} } private: A a; } 

A shared_ptr with user deletion is one way to achieve this without having to create an entire class for each type of resource.

You can improve the disabling of exceptions (for example, the problem log), depending on what is selected.

Better yet, modify the resources of A, B, and C so that they are cleaned up in their own destructors. However, this may not be possible.

In any case, you can place as many resources in one class as you want, without adding any code to the class destructor. This is scalability. The whole point of RAII is that each resource user does not need to write a cleanup code in order to properly use the resource.

+5
source share

Grab everything that your destructor can insert with catch-all (i.e. catch (...)) and do your best to handle the thrown exceptions. Make sure that no exceptions are thrown from the destructor that can help you prevent it.

+2
source share

You can also wrap ClearResources functions so they never throw. Why can they quit anyway?

+2
source share

Since you asked about the design pattern , Iโ€™ll tell you which thumb rule Iโ€™m using successfully. All functions that have a clean / end function should NEVER throw.

These functions are usually well-recognized names:

  • Clear * ()
  • Clean * ()
  • Terminate * ()
  • Destroy * ()
  • Release * ()
  • Detach * ()
  • Free * ()
  • Erase * ()
  • ~ destructor ()
  • ...

The rationale behind this is as follows:

  • at least 1 function per resource, which ensures that a certain resource is cleared
  • (recursively) if you create a cleanup function and free up multiple resources, then use only those functions that guarantee that these resources will be released in a safe way
  • programmers who use your code must have a way to clear the resource
  • if you export cleanup functions outside the library, then do not throw an exception (since library users do not know if the resource is freed)

And I can try to use the RAII pattern . But even then, the rules will be used.

+1
source share
 try { ClearResourceA(); } catch(...) { ExceptionWasThrown(); } try { ClearResourceB(); } catch(...) { ExceptionWasThrown(); } ... 
0
source share

All Articles