More Effective C++ 13: Catch exceptions by reference
You can catch exceptions by pointer, by value or by reference.
1. Catching exceptions by pointer leaves us with the question of whether to delete the pointer. When you write
static exception e;
throw (&e);
you definitely don't want to delete the pointer caught by catch. But if you write
exception * e=new exception;
throw(&e);
you will suffer from memory leaks if you don't delete the pointer. So you better not catch exceptions by pointer.
2. Catching exceptions by value also causes trouble. First, the exception objects will be copied twice, as disscussed in Item 12. Moreover, it gives rise to the specter of the slicing problem.
class exception { // as above, this is a
public: // standard exception class
virtual const char * what() throw();
// returns a brief descrip.
... // of the exception (see
// Item 14 for info about
}; // the "throw()" at the
// end of the declaration)
class runtime_error: // also from the standard
public exception { ... }; // C++ exception hierarchy
class Validation_error: // this is a class added by
public runtime_error { // a client
public:
virtual const char * what() throw();
// this is a redefinition
... // of the function declared
}; // in class exception above
void someFunction() // may throw a validation
{ // exception
...
if (a validation test fails) {
throw Validation_error();
}
...
}
void doSomething()
{
try {
someFunction(); // may throw a validation
} // exception
catch (exception ex) { // catches all exceptions
// in or derived from
// the standard hierarchy
cerr << ex.what(); // calls exception::what(),
... // never
} // Validation_error::what()
}
3. Catching exceptions by reference will solve all the problems above. So you should always catch exceptions by reference.