I\'ve seen at least one reliable source (a C++ class I took) recommend that application-specific exception classes in C++ should inherit from std::exception
. I\
Yes you should derive from std::exception
.
Others have answered that std::exception
has the problem that you can't pass a text message to it, however it is generally not a good idea to attempt to format a user message at the point of the throw. Instead, use the exception object to transport all relevant information to the catch site which can then format a user-friendly message.
The reason why you might want to inherit from std::exception
is because it allows you to throw an exception that is caught according to that class, ie:
class myException : public std::exception { ... };
try {
...
throw myException();
}
catch (std::exception &theException) {
...
}
Since the language already throws std::exception, you need to catch it anyway to provide decent error reporting. You may as well use that same catch for all unexpected exceptions of your own. Also, almost any library that throws exceptions would derive them from std::exception.
In other words, its either
catch (...) {cout << "Unknown exception"; }
or
catch (const std::exception &e) { cout << "unexpected exception " << e.what();}
And the second option is definitely better.
There is one problem with inheritance that you should know about is object slicing. When you write throw e;
a throw-expression initializes a temporary object, called the exception object, the type of which is determined by removing any top-level cv-qualifiers from the static type of the operand of throw
. That could be not what you're expecting. Example of problem you could find here.
It is not an argument against inheritance, it is just 'must know' info.
Another reason to sub-class exceptions is a better design aspect when working on large encapsulated systems. You can reuse it for things such as validation messages, user queries, fatal controller errors and so on. Rather than rewriting or rehooking all of your validation like messages you can simply "catch" it on the main source file, but throw the error anywhere in your entire set of classes.
e.g. A fatal exception will terminate the program, a validation error will only clear the stack and a user query will ask the end-user a question.
Doing it this way also means you can reuse the same classes but on different interfaces. e.g. A windows application can use message box, a web service will show html and reporting system will log it and so on.
Though this question is rather old and has already been answered plenty, I just want to add a note on how to do proper exception handling in C++11, since I am continually missing this in discussions about exceptions:
It is described on StackOverflow here and here, how you can get a backtrace on your exceptions inside your code without need for a debugger or cumbersome logging, by simply writing a proper exception handler which will rethrow nested exceptions.
Since you can do this with any derived exception class, you can add a lot of information to such a backtrace! You may also take a look at my MWE on GitHub, where a backtrace would look something like this:
Library API: Exception caught in function 'api_function'
Backtrace:
~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed
~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt"
std::runtime_error
in order to get plenty of information when an exception is thrown.The only benefit I see in subclassing (instead of just using std::runtime_error
) is that your exception handler can catch your custom exception and do something special. For example:
try
{
// something that may throw
}
catch( const MyException & ex )
{
// do something specialized with the
// additional info inside MyException
}
catch( const std::exception & ex )
{
std::cerr << ex.what() << std::endl;
}
catch( ... )
{
std::cerr << "unknown exception!" << std::endl;
}