Bruce Eckel's Thinking in C++, 2nd Ed | Contents | Prev | Next |
//: C23:Cleanup.cpp // Exceptions clean up objects #include <fstream> #include <exception> #include <cstring> using namespace std; ofstream out("cleanup.out"); class Noisy { static int i; int objnum; enum { sz = 40 }; char name[sz]; public: Noisy(const char* nm="array elem") throw(int){ objnum = i++; memset(name, 0, sz); strncpy(name, nm, sz - 1); out << "constructing Noisy " << objnum << " name [" << name << "]" << endl; if(objnum == 5) throw int(5); // Not in exception specification: if(*nm == 'z') throw char('z'); } ~Noisy() { out << "destructing Noisy " << objnum << " name [" << name << "]" << endl; } void* operator new[](size_t sz) { out << "Noisy::new[]" << endl; return ::new char[sz]; } void operator delete[](void* p) { out << "Noisy::delete[]" << endl; ::delete []p; } }; int Noisy::i = 0; void unexpected_rethrow() { out << "inside unexpected_rethrow()" << endl; throw; // Rethrow same exception } int main() { set_unexpected(unexpected_rethrow); try { Noisy n1("before array"); // Throws exception: Noisy* array = new Noisy[7]; Noisy n2("after array"); } catch(int i) { out << "caught " << i << endl; } out << "testing unexpected:" << endl; try { Noisy n3("before unexpected"); Noisy n4("z"); Noisy n5("after unexpected"); } catch(char c) { out << "caught " << c << endl; } } ///:~
constructing Noisy 0 name [before array] Noisy::new[] constructing Noisy 1 name [array elem] constructing Noisy 2 name [array elem] constructing Noisy 3 name [array elem] constructing Noisy 4 name [array elem] constructing Noisy 5 name [array elem] destructing Noisy 4 name [array elem] destructing Noisy 3 name [array elem] destructing Noisy 2 name [array elem] destructing Noisy 1 name [array elem] Noisy::delete[] destructing Noisy 0 name [before array] caught 5 testing unexpected: constructing Noisy 6 name [before unexpected] constructing Noisy 7 name [z] inside unexpected_rethrow() destructing Noisy 6 name [before unexpected] caught z