Correct way to inherit from std::exception

C++Exception

C++ Problem Overview


I've just created exception hierarchy and wanted to pass char* to constructor of one of my derived classes with a message telling what's wrong, but apparently std::exception doesn't have constructor which would allow me to do so. Yet there is a class member called what() which would suggest that some information can be passed.
How can I (can I?) pass text to derived class of a std::exception in order to pass info with my exception class, so I can say somewhere in the code:

throw My_Exception("Something bad happened.");

C++ Solutions


Solution 1 - C++

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_;
};

Solution 2 - C++

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.

Solution 3 - C++

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...

Solution 4 - C++

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.

Solution 5 - C++

The what method is virtual, and the meaning is that you should override it to return whatever message you want to return.

Solution 6 - C++

Here is an example

 class CommunicationError: public std::exception {
  public:
   explicit CommunicationError(const char* message) : msg(message) {}
   CommunicationError(CommunicationError const&) noexcept = default;

   CommunicationError& operator=(CommunicationError const&) noexcept = default;
  ~CommunicationError() override = default;

  const char* what() const noexcept override { return msg; }
 private:
  const char* msg;
};

[1] https://www.autosar.org/fileadmin/user_upload/standards/adaptive/17-03/AUTOSAR_RS_CPP14Guidelines.pdf

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsmallBView Question on Stackoverflow
Solution 1 - C++tune2fsView Answer on Stackoverflow
Solution 2 - C++obmargView Answer on Stackoverflow
Solution 3 - C++user472155View Answer on Stackoverflow
Solution 4 - C++JohannesView Answer on Stackoverflow
Solution 5 - C++Some programmer dudeView Answer on Stackoverflow
Solution 6 - C++rjhcnfView Answer on Stackoverflow