|
|
The approach taken by the client programmer
in the last section has one drawback:
MAXINT may actually be a valid element of the stack but will be skipped in the
process of printing.
Another solution to the overflow problem is to ask the library
to appoint the following initial handler to handle Stack::overflow
Objections:
int dec_pnum(const char*) // won't use error message
{
extern int pnum;
pnum--;
return 1;
}
This initial handler decrements pnum
whenever
an integer is
push()
'ed onto a full stack to offset the fact that
it will be incremented upon return to
silly_routine()
. dec_pnum()
returns a non- zero integer to ensure that
the subsequent handler is bypassed and
the recovery action takes place.
silly_routine()
now becomes:
void silly_routine()
{
Stack::overflow.appoint(dec_pnum); // added line
int i;
while( cin >> i ) {
st.push(i);
pnum++;
}
while(pnum > 0) {
cout << st.pop() << "\ n";
pnum--;
}
}
Now, the program will not abort; and MAXINT can be recognized as a valid element of the Stack.
On the other hand, let's assume that the
client programmer feels that continuing
the program is useless if the contents of
the entire file have not been read in.
The programmer really wants the program to abort on any error,
but would like to
save some information before it happens.
One solution is to define an initial handler
called cleanup()
, which prints the current contents
of the stack:
int cleanup(const char* msg)
{
extern int pnum;
extern Stack st;
// error message from library
cerr << msg << ": cleaning up\ n";
while(pnum > 0) {
cout << st.pop() << "\ n";
pnum--;
}
return 0;
}
and appoint it to handle overflow errors as follows:
void silly_routine()
{
Stack::overflow.appoint(cleanup); // added line
int i;
while( cin >> i ) {
st.push(i);
pnum++;
}
while(pnum > 0) {
cout << st.pop() << "\ n";
pnum--;
}
}
The cleanup()
initial handler returns 0 so
that the subsequent handler (the default action
error()
, which calls abort()
)
will take place upon return.
It could also have chosen to exit or abort after printing
the stack, so that neither the subsequent handler
default action nor the recovery
action would take place.