/************************************************************************ *
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.
* ************************************************************************/