I'm trying to override the what function in order to print customized error messages of my own.
all messages have the same beginning and therefore I thought that it would be best if I could do the following :
class Exception : public std::exception
{
public:
virtual const char* what() const throw() noexcept
{
return ("A game related error has occurred: " "class name");
//note : "class name" above is the error message I want to print
//depending on the situation, which can vary a lot(we have 8 different messages)
}
};
//examples of "class name" /otherwise known by us as error messages:
class IllegalArgument : public Exception {};
class IllegalCell : public Exception {};
my problem is the following :
I couldn't quite figure out how I can print a varying message depending on which error I receive without making a special what function in each error class - meaning I had to add a what function to IllegalArgument,IllegalCell and every other error class, which is bad in my eyes because it's too many functions to uphold and keep updating overtime. is there anyway I can avoid that, and just be able to print a varying message in the main class - Exception?
CodePudding user response:
You can pass the name of the class to Exception
constructor and store the name:
class Exception : public std::exception {
public:
virtual const char *what() const noexcept {
return m_.c_str();
}
protected:
Exception(std::string const& name) : m_{"A game related error has occurred: " name} {}
private:
std::string m_;
};
class IllegalArgument: public Exception {
public:
IllegalArgument() : Exception("IllegalArgument") {}
};
You can write a macro to define your child exceptions if you don't want to bother writing the default constructor each time.
Another option if you are fine with having generated names, is to use typeid()
, e.g.
class Exception : public std::exception {
public:
virtual const char *what() const noexcept {
// you need a static here to maintain the buffer since you are returning a
// const char*, not a string, and you cannot construct this string in the
// constructor because typeid() will not work properly in the constructor
//
static const std::string s =
std::string("A game related error has occurred: ") typeid(*this).name();
return s.c_str();
}
};
class IllegalArgument : public Exception { };
The name generated by typeid(*this).name()
is not standard, e.g., wit gcc I get 15IllegalArgument
, so that's up to you.