Correct way to inherit from std::exception
If you want to make use of the string constructor, you should inherit from std::runtime_error or std::logic_error which implements a string constructor and implements the std::exception::what method.
Then it's just a case of calling the runtime_error/logic_error constructor from your new inherited class, or if you're using c++11 you can use constructor inheritance.
I use the following class for my exceptions and it works fine:
class Exception: public std::exception
{
public:
/** Constructor (C strings).
* @param message C-style string error message.
* The string contents are copied upon construction.
* Hence, responsibility for deleting the char* lies
* with the caller.
*/
explicit Exception(const char* message)
: msg_(message) {}
/** Constructor (C++ STL strings).
* @param message The error message.
*/
explicit Exception(const std::string& message)
: msg_(message) {}
/** Destructor.
* Virtual to allow for subclassing.
*/
virtual ~Exception() noexcept {}
/** Returns a pointer to the (constant) error description.
* @return A pointer to a const char*. The underlying memory
* is in posession of the Exception object. Callers must
* not attempt to free the memory.
*/
virtual const char* what() const noexcept {
return msg_.c_str();
}
protected:
/** Error message.
*/
std::string msg_;
};
How about this:
class My_Exception : public std::exception
{
public:
virtual char const * what() const { return "Something bad happend."; }
};
Or, create a constructor accepting the description if you like...
If your goal is to create an exception so that you do not throw a generic exception (cpp:S112) you may just want to expose the exception you inherit from (C++11) with a using declaration.
Here is a minimal example for that:
#include <exception>
#include <iostream>
struct myException : std::exception
{
using std::exception::exception;
};
int main(int, char*[])
{
try
{
throw myException{ "Something Happened" };
}
catch (myException &e)
{
std::cout << e.what() << std::endl;
}
return{ 0 };
}
As Kilian points out in the comment section the example depends on a specific implementation of std::exception that offers more constructors than are mentioned here.
In order to avoid that you can use any of the convenience classes predefined in the header <stdexcept>
. See these "Exception categories" for inspiration.