Reputation:
This might be kind of a silly question, but in C++, when I want to throw an exception.. what do I throw?
Am I supposed to throw std::exception, or is that reserved by the standard library? Or should I throw a string or int? Or should I just throw whatever I feel is appropriate?
Upvotes: 25
Views: 2459
Reputation: 477040
Throw a class that's derived from std::exception
; if you #include <stdexcept>
, you can pick from a number of ready-made, useful derived classes.
Deriving from std::exception
allows your handlers to follow a recognizable style, as you can always use .what()
to get a textual message. Don't throw primitive types, since they carry no semantic information.
Upvotes: 32
Reputation: 490128
The primary exception to throwing something derived from std::exception
would be if you're using some framework (e.g., MFC) with its own exception hierarchy. In that case, you generally want to derive from an appropriate spot in their hierarchy instead.
Note that I'm not particularly attempting to hold MFC up as an example of clean exception handling (or clean design in general), only an example of a framework that includes an exception hierarchy. When you're using a framework that already defines an exception hierarchy, you're generally better off using it.
In other words, unlike the preference in C++ otherwise, it's generally accepted that exceptions should be a single, monolithic hierarchy with a single root. For the standard library, that single root is std::exception
, but other frameworks have alternatives, and if they provide one you generally want to fit yours into it.
Upvotes: 2
Reputation: 308168
Usually you'll want to throw one of the exceptions derived from std::exception
as others have said.
On occasion I've thrown other types, but only if it's caught within the same block and the value is something useful in that context.
Upvotes: 0
Reputation: 17441
Unlike java you CAN throw whatever (int, string, MyClass, ...
) you want. But listen to Kerrek. :)
Upvotes: 1
Reputation: 6797
Generally people don't throw std::exception directly for the simple reason that it doesn't store any error messages. There wouldn't be anything for the what method to return. I get confused sometimes over this because MSVC provides a non-standard extension to this a parameterized constructor in std::exception that accepts a string.
You can choose among existing exception classes like std::runtime_exception or define your own. This is somewhat subjective but I recommend keeping the number of exception classes to a minimum as RAII can eliminate a lot of the need to have multiple code branches and catch blocks for different exception types. Often the message combined with RAII-conforming code is enough to gracefully recover from any exception.
And finally, I recommend all exceptions you throw inherit from std::exception for similar reasons. You don't want to have to litter your code with many different catch blocks for different exception types if you can avoid it. Solve the problem as generally as you can.
Upvotes: 8