|
Guard Classes To Guarantee Post-Condition
Submitted by |
In many cases, a function has multiple error-checking points. Take a
file-load routine: Open file, read header, read data, process data. Each
sub-task could potentially generate an error that prevents the next sub-task
to execute properly.
There are several ways to handle this, all of which have their own problems.
One option is to use multiple return statements, which makes for pretty
readable code compared to, for instance, nested if-statements:
bool ReadFile()
{
if (!OpenFile())
return false;
if (!ReadHeader())
return false;
if (!ReadData())
return false;
if (!ProcessData())
return false;
return true;
} |
The problem here is when you need to do some clean-up before returning.
Maybe you allocate some memory or you are multi-threading and the function
is surrounded by a mutex-lock. In that case you would need to add the
pre-exit code to every instance of the return statement. Even if you put
this extra code in a separate function, it doesn't exactly improve
readability.
A solution to this problem is to use guard-classes that are used exclusively
as local (stack-)variables:
class MutexGuard
{
public:
MutexGuard() {Mutex.lock();}
~MutexGuard() {Mutex.unlock();}
}
bool ReadFile()
{
MutexGuard aMutexGuard;
if (!OpenFile())
return false;
if (!ReadHeader())
return false;
...etc...
} |
You don't do anything with this object, but as soon as you exit the function
(By whatever means, even an exception), the destructor will be called, and
the mutex will be unlocked properly.
Jeroen
|
The zip file viewer built into the Developer Toolbox made use
of the zlib library, as well as the zlibdll source additions.
|