Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception in destructor

Tags:

c++

In my destructor, I have to clean up a few resources. Let say I have three calls to clear resources that could throw. Since it is not good for letting an exception to leave a destructor, what should be my design pattern? Apparently the way below is not scalable.

Thanks.

class B::~B(){

try{
   clearResourceA()
 }
 catch{
     try{
         clearResourceB();
        } 
     catch{
         clearResourceC();
     }
     clearResourceC();
 }
clearResourceB();
    .
    .
}
like image 690
Steveng Avatar asked Oct 14 '10 14:10

Steveng


3 Answers

Why not:

try{clearResourceA();} catch(...){}
try{clearResourceB();} catch(...){}
try{clearResourceC();} catch(...){}
like image 151
Benoit Avatar answered Oct 13 '22 18:10

Benoit


Encapsulate each resource in a class which clears them in its destructor (with a 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 a custom deleter is one way to achieve this without having to create a whole class for each type of resource.

You might improve on discarding the exception (log the problem, for example), depending what's thrown.

Even better, modify resources A, B and C so that they clear themselves in their own destructors. That might not be possible, though.

Either way, you can then put as many such resources in a single class as you like, without adding any code to the destructor of the class. This is "scalability". The whole point of RAII, is that each user of a resource shouldn't have to write cleanup code in order to use the resource correctly.

like image 27
Steve Jessop Avatar answered Oct 13 '22 18:10

Steve Jessop


Capture anything that can throw in your destructor with a catch-all (i.e., catch (...)) and do your best to handle the exceptions thrown. Make sure that no exceptions propagate out of the destructor, which the catch-all will help you prevent.

like image 43
Michael Goldshteyn Avatar answered Oct 13 '22 19:10

Michael Goldshteyn