Managing Resources with Constructors and Destructors


/************************************************************************
*

Exception handling can be used in conjunction with constructors and destructors to provide resource management that ensures that all locked resources are unlocked when an exception is thrown. For example:

                                                                        *
************************************************************************/

class data
{
      public:
            void lock();      // prevent other users from
                              // changing the object
            void unlock();    // allow other users to change
                              // the object
};
void q(data&), bar(data&);
// ...
main()
{
      data important;
      important.lock();
      q(important);
      bar(important);
      important.unlock();
}

/************************************************************************
*

If q() or bar() throw an exception, important.unlock() will not be called and the data will stay locked. This problem can be corrected by using a helper class to write an exception-aware program for resource management.

                                                                        *
************************************************************************/

class data
{
      public:
            void lock();      // prevent other users from
                              // changing the object
            void unlock();    // allow other users to change
                              // the object
};
class locked_data             // helper class
{
      data& real_data;
      public:
            locked_data(data& d) : real_data(d)
                              {real_data.lock();}
            ~locked_data() {real_data.unlock();}
};
void q(data&), bar(data&);
// ...
main()
{
      data important;
      locked_data my_lock(important);
      q(important);
      bar(important);
}

/************************************************************************
*

In this case, if q() or bar() throws an exception, the destructor for my_lock will be called, and the data will be unlocked.

                                                                        *
************************************************************************/