#include #include #include using namespace std; // This is an example of writing our own exception types. // It is not _technically_ necessary to derive from the // std::exception class, but it is an EXTREMELY good idea. class myException : public exception { public: // This is one of the very very few places where it is actually // better to use char* rather than string. We reduce the danger // of using char* by making sure it is const. It is important // to do this here because if our exception is being thrown because // of running out of memory, then allocating a new string object // is going to make things worse. myException(const char* data) { myData = data; } // This is basically just like .what() on many of std:exception's // decendent types. const char* errorMsg() { return myData; } private: // The error message we will throw const char* myData; }; // Predeclare foo. We are being polite by listing off those exceptions // that might be thrown. void foo(int n) throw (bad_cast, logic_error, myException); int main() { int t; // This try is to demonstrate the use of bad_exception try { // By putting the while loop around the try/catch blocks, // we continue looping even in the face of an exception while (cin >> t) { try { // Call foo with our input foo(t); } // We need to list these in order of generality: most specific // in the std::exception tree to least specific (exception or ...) catch (myException& e) { cout << e.errorMsg() << endl; } catch (logic_error& e) { cout << e.what() << endl; cout << "That was a logic error!" << endl; } // If everyone behaves nicely and derives their exceptions from // std::exception, then we can ALWAYS do this as a last resort, // rather than using catch (...), which can cause really bad // behavior on some OSs. catch (exception& e) { // Is this how bad_exception is supposed to be used? // So far as we can see, yes. throw bad_exception(); } } } catch (bad_exception& e) { cout << "BAD EXCEPTION!" << endl; } } // Note that the signature here must match the pre-declaration void foo(int n) throw (bad_cast, logic_error, myException) { // Some silly behavior to demonstrate exceptions if (n == 5) throw bad_cast(); if (n == -10) throw logic_error("Logic error!"); if (n < 0) throw myException("Bad argument, dude (myexception)."); cout << n << endl; }