/* Author: Arun Somasundaram, CSE Dept, OSU. Program to test exceptions. Different examples of exceptions are provided. */ #include #include #include using namespace std; /************************DivideByZero class*********************/ class DivideByZero{ private: char *str; public: DivideByZero(char *s); DivideByZero(const DivideByZero &d); ~DivideByZero(); char * outputError() const {return str;} }; DivideByZero::DivideByZero(char *s){ str = new char[strlen(s) + 1]; strcpy(str, s); cout << s << " " ; cout << "Constructor DivideByZero being called." << endl; } DivideByZero::DivideByZero(const DivideByZero &d){ cout << "Inside Copy Constructor" << endl; if (this != &d){ if (d.str != NULL){ delete [] str; } str = new char[strlen(d.str) + 1]; strcpy(str, d.str); } } DivideByZero::~DivideByZero(){ cout << str << " " ; if (str != NULL){ delete [] str; } cout << "Destructor DivideByZero being called. " << endl; } /**************** quotient throws exception **********************/ int quotient(int val, int d){ cout << "Inside Quotient function." << endl; int q; if (d == 0){ DivideByZero * dbz = new DivideByZero("I am a pointer"); throw DivideByZero("Division by zero - Class"); //1 //throw "Division by zero (Using const char *)"; //2 //throw 100; //3 //unblock 2 or 3 and block 1 and test. Which catch is called? cout << " After throw DivideByZero()"<< endl; } else{ q = val/d; } cout << " Before return q" << endl; return q; } //******************** used to handle unhandled exceptions****/ void terminateFunction(){ cout << "Terminate Function is being called" << endl; cout << "That was because no corresponding catch was found." << endl; //When is this function called when you run the program? Why? exit(-1); } /********************Function exception specifications****/ /* These are dummy functions*/ //Exceptions thrown/caught affect the way a function relates to other functions. You can add the exceptions thrown information in the function declaration. int fThrowsAnyException(){ //can throw any exception - default //Statements return 0; } int fThrowsNoException() throw() { //throws no exception //Statements return 0; } int fThrowsSpecifiedExceptions() throw(DivideByZero, char *){//throws the specified exceptions //Statements return 0; } /******************Exceptions in Constructors*********************/ class CoinHolder{ public: int cNum; static const int max = 100; class Size{ private: int num; public: Size(int n){num = n;} int mySize(){return num;} }; CoinHolder(){} CoinHolder(int n){ if ((n < 0) || (n > max)) throw Size(n); else cNum = n; } }; class DimeHolder:public CoinHolder{ //Derived Class private: int type; public: DimeHolder(int n); //Other functions }; DimeHolder::DimeHolder(int n) try :CoinHolder(n) { type = 1; } catch(CoinHolder::Size s){ cout << s.mySize() << " Exceeds limit of coin/dimeholder." << endl; } void testCoinDimeHolderLimits(){ try{ CoinHolder cH(1000); } catch(CoinHolder::Size s){ cout << s.mySize() << " Exceeds limit of coinholder." << endl; } try{ DimeHolder dH(1000); } catch(CoinHolder::Size s){ cout << s.mySize() << " Exceeds limits." << endl; } } /******************Derived Exceptions***************************/ class MathError{ public: virtual void print(){cout << "Math Error" << endl;} }; class IntOverflow:public MathError{ public: virtual void print(){cout << "Int Overflow Error" << endl;} }; class IntUnderflow:public MathError{ public: virtual void print(){cout << "Int Underflow Error" << endl;} }; int add(int a, int b){ if (a > (INT_MAX - b)) throw IntOverflow(); return( a + b); } int subtract(int a, int b){ if (a < (INT_MIN + b)) throw IntUnderflow(); return( a - b); } void testDerivedExceptions(){ try{ int a = INT_MAX; int c = add(a, 10); } catch(MathError &e){ //e is reference type e.print(); } //What is the difference between the above and below try/catch try{ int a = INT_MAX; int c = add(a, 10); } catch(MathError e){ e.print(); } try{ int a = INT_MAX; int c = add(a, 10); } catch(IntOverflow e){ e.print(); } catch(MathError e){ e.print(); } try{ int a = INT_MIN; int c = subtract(a, 10); } //What exception should actually be caught here? catch(IntOverflow e) {//handle IntOverflow or its derived exceptions e.print(); } catch(MathError e){//handle MathError exceptions that is not IntOverflow e.print(); } } /****************A couple of standard exceptions***************/ void memoryProblem(){ int * a; int b = 100000; int c = 100000; a = new int[b*c]; } void outOfBoundsProblem(int index){ vector v; for(int i = 0; i < 5; i++){ v.push_back(3); } cout << v.at(index) << endl; } /*****************************************************************/ int main(){ int val, d; cout << "Enter dividend "; cin >> val; cout << "Enter divisor "; cin >> d; cout << endl << "******************* Example 1 **************" << endl; cout << "Dividing " << val << " by " << d << endl; try{ cout << "Inside TRY, before quotient" << endl; int q = quotient(val, d); cout << "Quotient is " << q << endl; cout << "Inside TRY, after quotient" << endl; } catch(DivideByZero d){ cout << "***Inside CATCH DivideByZero***" << endl; cout << d.outputError() << endl; } catch(char *s){ cout << "***Inside CATCH const char* ***" << endl; cout << "Exception: " << s << endl; } catch(...){ //Catches everything. //This catch(...) if included, should be the last catch... // handler for a try block. Why? cout << "***Catches everything.***" << endl; } cout << "After try and catch" << endl; cout << endl << "******************* Example 2 **************" << endl; testCoinDimeHolderLimits(); cout << endl << "******************* Example 3 **************" << endl; testDerivedExceptions(); cout << endl << "******************* Example 4 ***************" << endl; try{ memoryProblem(); } catch(std::bad_alloc){ cout << "Bad allocation" << endl; } try{ outOfBoundsProblem(7); } catch(std::out_of_range){ cout << "Out of range" << endl; } cout << endl << "******************* Example 5 **************" << endl; //What happens if you do not provide a catch handler to handle the corresponding thrown exception? try{ set_terminate(terminateFunction); cout << "Inside TRY, before quotient" << endl; int q = quotient(val, d); cout << "Quotient is " << q << endl; cout << "Inside TRY, after quotient" << endl; } catch(char *s){ cout << "***Inside CATCH const char* ***" << endl; cout << "Exception: " << s << endl; } cout << "End of Program." << endl; }