void f() throw(toobig, toosmall, divzero);
void f();
void f() throw();
//: C01:Unexpected.cpp // Exception specifications & unexpected(), //{-msc} (Doesn't terminate properly) #include <exception> #include <iostream> using namespace std; class Up {}; class Fit {}; void g(); void f(int i) throw(Up, Fit) { switch(i) { case 1: throw Up(); case 2: throw Fit(); } g(); } // void g() {} // Version 1 void g() { throw 47; } // Version 2 void my_unexpected() { cout << "unexpected exception thrown" << endl; exit(0); } int main() { set_unexpected(my_unexpected); // (Ignores return value) for(int i = 1; i <=3; i++) try { f(i); } catch(Up) { cout << "Up caught" << endl; } catch(Fit) { cout << "Fit caught" << endl; } } ///:~
Listado 2.14. C01/Unexpected.cpp
//: C01:BadException.cpp {-bor} #include <exception> // For std::bad_exception #include <iostream> #include <cstdio> using namespace std; // Exception classes: class A {}; class B {}; // terminate() handler void my_thandler() { cout << "terminate called" << endl; exit(0); } // unexpected() handlers void my_uhandler1() { throw A(); } void my_uhandler2() { throw; } // If we embed this throw statement in f or g, // the compiler detects the violation and reports // an error, so we put it in its own function. void t() { throw B(); } void f() throw(A) { t(); } void g() throw(A, bad_exception) { t(); } int main() { set_terminate(my_thandler); set_unexpected(my_uhandler1); try { f(); } catch(A&) { cout << "caught an A from f" << endl; } set_unexpected(my_uhandler2); try { g(); } catch(bad_exception&) { cout << "caught a bad_exception from g" << endl; } try { f(); } catch(...) { cout << "This will never print" << endl; } } ///:~
Listado 2.15. C01/BadException.cpp