Re: Throw from a destructor
On Fri, 7 Jul 2006 22:14:31 GMT, Joe Van Dyk <joe.vandyk@boeing.com>
wrote:
Phlip wrote:
C++ers:
I have this friend who thinks C++ cannot throw from a destructor.
I think throwing from a destructor is bad Karma, and should be designed
around, but that C++ cannot strictly prevent the actual event.
(Scott Meyer's Effective C++ 3rd edition, Item 8 addresses exactly this.)
How about something like (almost verbatim from the book):
class BigSimCity
{
void shutdown()
{
// do stuff that may throw
closed_ = true;
}
~BigSimCity() // would this have an empty throw() specification?
{
if (!closed)
{
try { shutdown(); }
catch (...) { // log or something }
}
}
private:
bool closed;
};
You give the client the chance to shutdown() on their own if they want
catch it on their own. And if not, then shutdown()'s called by the
destructor.
The above works in some circumstances but is not a general solution.
It forces the client to write try-catch blocks, e.g.
try {
// ...
mySimCity.shutdown();
} catch (SimCityException& e) {
// do something
} catch (...) {
// do somethig else
}
In general, when the shutdown function produces meaningful output
(exception or return value) for the user it cannot be called in the
destructor.
Take as an example (good and bad) iostreams. When the file is opened
read-only then you can ignore the return value from close(). But when
the file is opened for write you cannot ignore the return value from
close(). Iostreams do not distinguish that cases and use the wrong
default.
Your example may be re-written in the following way:
class BigSimCity
{
bool commit()
{
// do stuff that may throw
closed_ = true;
return closed_;
}
void rollback() throw()
{
// do stuff that cannot throw or for which you
// can ignore exceptions and return values
}
~BigSimCity() throw()
{
if (!closed)
{
rollback();
}
}
private:
bool closed;
};
Best wishes,
Roland Pibinger