/// Description: This program shows the relationships between all (most?) exceptions defined in the c++ standard. A template function, TestInheritance, uses the dynamic cast operator to try to convert a pointer of two different exception types to one another. An upcast, returns a valid pointer. A downcast, or a cast to an unrelated type, returns a null. #include #include #include #include #include using namespace std; template void TestInheritance( X& x, Y& y, const char *pretty_x, const char *pretty_y) { X *px = &x; Y *py = &y; X* pX = dynamic_cast(py); Y* pY = dynamic_cast(px); if (pX == NULL && pY == NULL) { cout << pretty_x << " and " << pretty_y << " are not related" << endl; } else if (pX != NULL && pY != NULL) { cerr << "a logic error has occured" << endl; exit( -1); } else if (pX != NULL && pY == NULL) { cout << pretty_y << " is a child of " << pretty_x << endl; } else if (pX == NULL && pY != NULL) { cout << pretty_x << " is a child of " << pretty_y << endl; } } class hack_ios_base : protected ios_base { public: hack_ios_base() {} static ios_base::failure FAIL; }; ios_base::failure hack_ios_base::FAIL( "failure"); int main(int argc, char* argv[]) { exception e; logic_error le( "logic_error"); runtime_error re( "runtime_error"); domain_error de( "domain_error"); invalid_argument ie( "invalid_argument"); length_error lne( "length_error"); out_of_range oor( "out_of_range"); range_error rne( "range_error"); underflow_error ue( "underflow_error"); overflow_error oe( "overflow_error"); bad_alloc ba; // thrown by new when a memory request fails bad_cast bc; // thrown by dynamic cast bad_typeid bt; // thrown by typeid when it dereferences a null bad_exception be; // unexpected exceptions ios_base::failure& ibf = hack_ios_base::FAIL; cout << "children of exception" << endl; TestInheritance( e, le, "exception", "logic_error"); TestInheritance( e, re, "exception", "runtime_error"); TestInheritance( e, ba, "exception", "bad_alloc"); TestInheritance( e, bc, "exception", "bad_cast"); TestInheritance( e, bt, "exception", "bad_typeid"); TestInheritance( e, be, "exception", "bad_exception"); TestInheritance( e, ibf, "exception", "io_base::failure"); cout << "\nchildren of logic error" << endl; TestInheritance( le, de, "logic_error", "domain_error"); TestInheritance( le, ie, "logic_error", "invalid_argument"); TestInheritance( le, lne, "logic_error", "length_error"); TestInheritance( le, oor, "logic_error", "out_of_range"); cout << "\nchildren of runtime error" << endl; TestInheritance( re, rne, "runtime_error", "range_error"); TestInheritance( re, ue, "runtime_error", "underflow_error"); TestInheritance( re, oe, "runtime_error", "overflow_error"); cout << "\nunrelated exceptions" << endl; TestInheritance( le, ba, "logic_error", "bad_alloc"); TestInheritance( re, ba, "runtime_error", "bad_alloc"); TestInheritance( le, bc, "logic_error", "bad_cast"); TestInheritance( re, bc, "runtime_error", "bad_cast"); TestInheritance( le, bt, "logic_error", "bad_typeid"); TestInheritance( re, bt, "runtime_error", "bad_typeid"); TestInheritance( le, be, "logic_error", "bad_exception"); TestInheritance( re, be, "runtime_error", "bad_exception"); return 0; }