Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inherit Exceptions in C++ [duplicate]

Tags:

c++

exception

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?

like image 315
Awesome36 Avatar asked Jan 12 '17 15:01

Awesome36


1 Answers

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.

like image 183
Dale Wilson Avatar answered Oct 14 '22 02:10

Dale Wilson