### 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.

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