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 )
{
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;
}
}

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:
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
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


Maintaining an exception stack
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