Midterm Assignment Morgan Stanley C++ Part
II
Your assignment for the midterm is to create several exception classes,
derived from a base exception class. While you may have seen examples of
this before, one important difference between this and previous examples
is that this class will automatically maintain an exception stack.
An exception stack is a data structure that maintains a list of all exceptions
that have occurred in succession. In otherwords, when a high-level operation
fails, it usually fails because a function it called failed. The function
that was called, may have failed because a function that it called failed,
and so on. The goal of the exception stack is to keep all of the exceptions
(failures) in an exception stack, so that they can be reviewed if the user
wishes.
The exception stack will give a program the ability to simply inform the
user that the program is unable to perform an operation, without cryptic
messages. But it also gives a programmer more detailed information about
exactly what chain of events caused the operation to fail.
Your test program for your exception classes should be the following:
int Prompt( char* Prompt, char* AllowedResponses
)
If this program is run, and the user
replies 'Y' to the 'Want Details' prompt, then a list of every exception
(two, in our demo) which has occured should be displayed. The output of
this program, on my demo program, was:
{
char Ch;
do {
cout << Prompt;
cout.flush();
cin >> Ch;
Ch = toupper(Ch);
} while( strchr( AllowedResponses, Ch ) == 0 );
return( Ch );
}
void FuncB()
{
throw new MSCUMemExcept( __LINE__, __FILE__);
}
void FuncA()
{
try {
FuncB();
}
catch(...) {
throw new MSCUFileExcept( __LINE__, __FILE__, "Can't open", "bogus.txt"
);
}
}
void main()
{
try {
FuncA();
}
catch( MSCUExcept* E ) {
if( Prompt( "Unable to perform operation. Want details?", "YN"
)=='Y')
MSCUExcept::Dump( cout, false );
//E = 0; // To satisfy compiler
}
catch( ... ) {
cout << "Unexpected exception?" << endl;
}
}
Unable to perform operation. Want details?Y
C:\Work\MS\cpp2\midexcp\midexcp.cpp: 121
Can't open[bogus.txt]
C:\Work\MS\cpp2\midexcp\midexcp.cpp: 111
Out of memory
The Base Exception class: MSCUExcept
The base exception class serves
two primary purposes:
Storing Exception information
The MSCUExcept class should have data
members that make it possible to store the following items:
You will find that the line number and filename are parameters to the MSCUExcept
constructor.
The pointer follows the design of a linked list. While it is termed an Exception
Stack, it should be implemented similar to how linked list is maintained,
but without many of the functions for list management. This pointer is needed
to maintain the exception stack.
The data definition for the data members described above should be:
string Message; // Holds message for
exception
Maintaining an exception stack
MSCUExcept * PrevException; // Address of previous exception
char* Filename; // Source code filename of where exception was thrown
int Line; // Source code line number of where exception was thrown
Each exception must be placed on the
exception stack. There is only one exception stack. You should write the
constructor of the MSCUExcpet class so that it places a pointer to the this
exception in the exception stack.
There should be 2 static data members to help maintain the stack:
static MSCUExcept * ExceptStack; // Pointer
to last exception to occur
static int ExceptionCount; // Count of exceptions in the exception stack
When an exception is added to the stack, you should take the current ExceptStack
value, and store it in the PrevException pointer for this.
You should then take the address of the this exception, and store
it to ExceptionStack. Finally (for managing the exception stack),
increment the ExceptionCount integer. This will make a 'daisy-chain'
of sorts, which is the Exception Stack.
Functions required for the MSCUException class
MSCUExcept(int NewLine, char*
NewFile )
Constructor. Initializes the Line, Filename, and PrevExcept
data members of the exception class. Will also add the this pointer
to the exception stack.
NewLine Line number
NewFile Source code filename
virtual ~MSCUExcept()
Destructor. Just decrements the ExceptionCount by one.
const string & GetMessage() const;
Returns the Message data member. Helpful in outputting the message
to the console, or a file.
int GetLine() const;
Returns the Line data member. Helpful in outputting the message to
the console, or a file.
char* GetFile() const;
Returns the Filename data member. Helpful in outputting the message
to the console, or a file.
static void ClearStack()
Removes all exceptions from the exception stack. You must delete
each pointer from the exception stack. The delete of the exception
object should call the MSCUExcept destructor (automically), which will decrement
the ExceptionCount data member.
static int GetExceptionCount()
Returns the ExceptionCount data member. Helpful when you want to
loop through all the exception in the stack.
static const MSCUExcept* GetExcept( int Index )
Returns the address of a specific exception, specified by Index,
from the exception stack. You will need to traverse the ExceptStack
pointer, like a linked list, as many times as specified by Index,
and then return the pointer that you stop on.
Index Specifies position within the stack. Zero indicates the last
exception to occur.
static void Dump( ostream& Dst, bool Clear=true )
Dumps (displays) all of the exception in the exception stack.
Dst an ostream, and may be either cout, or an open file stream
Clear If true, then the stack should be cleared after being output
(just call ClearStack)
Classes derived from MSCUExcept, in general
The primary purpose for classes
derived from MSCUExcept is to initialize the Message data member
(you will want to make the data members, or at least the Message
data member protected to do this easily). For that reason, you will
find that for the derived classes, you only need to write the constructor.
The constructor for the derived classes will need to provide an initializer
list, where it passes the Line and Filename parameters off
to the base class (MSCUExcept) constructor. The derived classes are divided
into types of errors so that identifying exception types in catch blocks
is possible.
The MSCUMemExcept class
The sole purpose of this class,
is to initialize the Message parameter to "Out of memory".
It has no data members of it's own, and only a constructor function.
Functions required for the MSCUMemExcept class
MSCUMemExcept( int NewLine, char
* NewFile );
Constructor. Since we will only be addressing one type of memory exception,
out of memory, this function only needs to set Message to "Out
of memory". See also the Notes section.
The MSCUFileExcept class
The purpose of this class is to
hold information regarding errors against a disk file. It will only have
a constructor whose purpose is to initialize Message with a description
of the operation that failed, and the filename that the operation failed
against. Like MSCUMemExcept, it has no data members of it's own,
and only a constructor function.
Functions required for the MSCUMemExcept class
MSCUFileExcept( int NewLine, char
* NewFile, char * Problem, char *Filename );
Constructor. This function should set Message to be Problem
+ ": [" + Filename + "]".
Notes