excep.cpp

// excep.cpp - Example of base and derived exception classes
//
//

#include <iostream.h>
#include <string.h>

// Our abstract, base exception class
class Exception
{
public: 
	Exception() { Msg[0] = '\0';}
	const char *GetMsg() const { return( Msg ); }
	virtual ~Exception() {};
	virtual const char * GetType() const =0;
protected:
	void SetData( char *nMsg ) { strcpy( Msg, nMsg ); }
	void AppendData( char *Src ) { 
		for( int i=strlen(Msg); i < sizeof(Msg)-1 && (Msg[i]=*Src++); i++ )
			Msg[i+1]='\0';
	}
	char Msg[128];
};

ostream& operator<<( ostream& o, const Exception& E ) // Note: E is a pointer to a base class
{
	o << "Exception of type " << E.GetType() << "\n" << E.GetMsg() << endl;
	return( o );
}

// Memory exception class, derived from Exception
class MemoryException : public Exception
{
public:
	MemoryException( char * Text ) { SetData( Text ); }
	virtual const char * GetType() const { return("MemoryException"); }
};

// File exception class, derived from Exception
class FileException : public Exception
{
public:
	FileException( char * Text, char *File ) { SetData(Text); AppendData(" : "); AppendData(File);}
	virtual const char * GetType() const { return("FileException"); }
};

// A support function, to ask the user something
int AskUser( char * Prompt )
{
	char Ch;
	cout << Prompt << endl;
	do {
		cin >> Ch;
		cin.ignore(1);
	} while( Ch!='n' && Ch!='N' && Ch!='y' && Ch!='Y' );
	return( Ch=='y' || Ch=='Y' );
}

// Function, to simulate a memory error
void GetMemory()
{
	if( AskUser( "Simulate a memory error?" ) )
		throw MemoryException( "GetMemoryFailed");
}
// Function, to simulate a file error
void GetFile()
{
	if( AskUser( "Simulate a file error?" ) )
		throw FileException( "GetFileFailed", "somefile");
}


void main()
{
	try {
		GetMemory();
		GetFile();
	}
	catch( Exception & E )	// Note how 1 handler, reports all exceptions
	{
		cout << E;
	}
}