///////////////////////////////////////////////////////////////////////////// // stdException.cpp - demonstrate Standard C++ exceptions // // Jim Fawcett, CSE691 - SW Modeling & Analysis, Fall 2000 ///////////////////////////////////////////////////////////////////////////// // Platform: Dell XPS1000, Windows 2000 Professional, SP1 #include #include #include ///////////////////////////////////////////////////////////////////////////// // function call tracer class trace { public: trace(char *s) : _s(s) { std::cout << "\n\n entering " << _s; } ~trace() { std::cout << "\n leaving " << _s; } private: char *_s; }; ///////////////////////////////////////////////////////////////////////////// // user defined exception class userException { public: userException() : _name("userException") { } const char* what() const throw() { return _name.c_str(); } private: std::string _name; }; ///////////////////////////////////////////////////////////////////////////// // better user defined exception - because its derived from exception base class betterUserException : public std::exception { public: betterUserException() : std::exception("betterUserException") { } virtual const char* what() const { return exception::what(); } void saveNumber(int num) { _number = num; } int savedNumber() { return _number; } private: int _number; }; // ///////////////////////////////////////////////////////////////////////////// // test manually throwing standard exceptions void throwStdException(std::exception &e) { trace t("throwStdException(exception &e)"); try { throw e; } catch(const std::exception &e) { std::cout << "\n caught " << e.what(); } catch(...) { std::cout << "\n caught non-standard exception"; } } ///////////////////////////////////////////////////////////////////////////// // test throwing user defined exception void throwUserException(userException &ue) { trace t("throwUserException(userException &ue)"); try { throw ue; } catch(const userException &ue) { std::cout << "\n caught " << ue.what(); } catch(...) { std::cout << "\n caught non-standard exception"; } } ///////////////////////////////////////////////////////////////////////////// // test throwing better user defined exception void throwBetterUserException(betterUserException &bue) { trace t("throwBetterUserException(betterUserException &bue)"); std::cout << "\n Here in throwBetterUserException(...) I'm saving a number"; std::cout.flush(); bue.saveNumber(10); throw bue; } // ///////////////////////////////////////////////////// // Structured Exception handling // // SEH isn't very useful: // - can't use with C++ exception handling in same function // - can't have an object with a destructor in same function // #include #include int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep) { if (code == EXCEPTION_INT_DIVIDE_BY_ZERO) { return EXCEPTION_EXECUTE_HANDLER; } else if (code == EXCEPTION_ACCESS_VIOLATION) { return EXCEPTION_EXECUTE_HANDLER; } else { return EXCEPTION_CONTINUE_SEARCH; }; } ///////////////////////////////////////////////////////////////////////////// // test divide by zero void divideByZero() { /////////////////////////////////////////////////////////////////////// // Unfortunately this try/catch needs a non-default property setting. // trace t("divideByZero()"); try { int x = 0, y = 1; int z = y/x; } catch(const std::exception &e) { std::cout << "\n caught " << typeid(e).name(); } catch(...) { std::cout << "\n caught non-standard exception"; } /////////////////////////////////////////////////////////////////////// // Structured Exception Handling // // __try // { // int x = 0, y = 1; // int z = y/x; // } // __except(filter(GetExceptionCode(), GetExceptionInformation())) // { // std::cout << "\n caught structured exception for divide by zero"; // } } // ///////////////////////////////////////////////////////////////////////////// // test memory access violation void memoryAccessViolation() { /////////////////////////////////////////////////////////////////////// // Unfortunately this try/catch needs a non-default property setting. // const char* StrArray[3]; StrArray[0] = "first"; StrArray[1] = "second"; StrArray[2] = "third"; trace t("memoryAccessViolation()"); try { for(int i=0; i<=3; ++i) { std::cout << "\n " << StrArray[i]; std::cout.flush(); } } catch(const std::exception &e) { std::cout << "caught " << typeid(e).name(); } catch(...) { std::cout << "caught non-standard exception"; } /////////////////////////////////////////////////////////////////////// // Structured Exception Handling // // __try // { // for(int i=0; i<=3; ++i) // std::cout << "\n " << StrArray[i]; // } // __except(filter(GetExceptionCode(), GetExceptionInformation())) // { // std::cout << "\n caught structured exception for Memory Access Violation"; // } } // ///////////////////////////////////////////////////////////////////////////// // test stub using namespace std; struct cosmetic { public: ~cosmetic() { std::cout << "\n\n"; } } cosm; void main() { trace t("main()"); cout << "\n Demonstrate Standard and User Defined Exceptions " << "\n ==================================================\n"; cout.flush(); try { divideByZero(); // exception caught in function memoryAccessViolation(); // exception caught in function bad_alloc ba; throwStdException(ba); // exception caught in function bad_cast bc; throwStdException(bc); // exception caught in function userException ue; throwUserException(ue); // exception caught in function betterUserException bue; bue.saveNumber(10); throwStdException(bue); // exception caught in function throwBetterUserException(bue); // does not catch its thrown exception } catch(betterUserException &e) { cout << "\n Here in Main:"; cout << "\n caught " << e.what(); cout << "\n savedNumber = " << e.savedNumber(); } catch(const userException &e) { cout << "\n caught " << e.what(); } catch(...) { cout << "\n caught non-standard exception"; } cout << "\n\n"; }