I've just created an exception hierarchy and want my catch-block to show the message of the derived exception. I got 5 exceptions like this one:
class ImagetypeException : public TGAException {
public:
const char* what() const throw();
};
const char* ImagetypeException::what() const throw() {
return "Der Bildtyp ist nicht \"RGB unkomprimiert\".";
}
All of them are derived from TGAException, that is derived from std::exception.
class TGAException : public std::exception {
public:
virtual const char* what() const throw();
};
const char* TGAException::what() const throw() {
return "Beim Einlesen oder Verarbeiten der TGA-Datei ist ein unerwarteter Fehler aufgetreten!";
}
So I obviously want to throw these at some point in my code and thought it might be a good idea, to minimize the amount of catch-blocks I need.
catch (TGAException e) {
cout << e.what() << endl;
}
If I do it like this, the message, that will be printed, is the one from TGAException, but I want it to show the more specific derived messages. So what excatly do I need to do to get this to work the way I want it to?
When you catch like this:
catch (TGAException e) {
cout << e.what() << endl;
}
The compiler makes a copy of the original exception and assigns it to e. It uses the TGAException copy constructor so the exception seen inside the catch block is not an ImagetypeException, it is a TGAException. This phenomenon is called object slicing.
If you catch it this way:
catch (const TGAException & e) {
cout << e.what() << endl;
}
No copy is needed and it will work the way you expect it to.
As a general guideline: Always catch exceptions by reference, and almost always catch them by const reference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With