|
|
Note that the library author could have chosen anything as the default action; and the default could have changed for each place in the code where an Objection is raised. However, the library author often wants to do essentially the same thing as a default action each time an Objection is raised. Because of this, there exists a way for the writer to specify a default action at the time an Objection is created.
Since the author of the Stack class has decided that executing
error()
will be the default action at each point,
the Objections could have been instantiated with the error()
routine as follows:
prog.c: includes definitions of Objections #include <Stack.h>
.
.
.
Objection Stack::underflow(error);
Objection Stack::overflow(error);
When Objections have been defined this way, raise()
executes this default function when appropriate (i.e., raise()
would have returned a 0).
The raise()
function can be passed an error message,
which will be passed to the default action routine. If raise()
returns non-zero, the recovery action should take place.
Let's look more closely at raise()
before
we continue.
raise()
calls two handlers
in tandem, where a handler is a function that returns int
(by convention, 1 indicates success and 0 failure in handling the error).
An initial handler will (unless later changed through
appoint()
or ignore()
)
simply return 0: its return value is the one returned by raise().
A subsequent handler describes an action to take
place; its return value is ignored.
error
is an example of a subsequent handler. Subsequent
handlers (the ``default action'') are executed when raise()
returns 0. When
raise()
returns a non-zero value through the use
of
appoint()
or ignore()
,
the default action is superseded and the recovery action will take place.
Given these definitions of the Objections, the push()
,
pop()
, and top()
routines could be written as follows:
void Stack::push(int i)
{
if(size == SIZE) {
// error condition
Stack::overflow.raise("Pushing full stack!");
return; // recovery action
}
else
stack[size] = i;
size++;
}
int Stack::pop()
{
size--;
if(size < 0) {
// error condition
Stack::underflow.raise("Popping empty stack!");
size = 0; // recovery action
return MAXINT;
}
else
return stack[size];
}
int Stack::top()
{
if(size == 0) {
// error condition
Stack::underflow.raise("Topping empty stack!");
return MAXINT; // recovery action
}
else
return stack[size-1];
}