在 C++ 中覆盖 std::exception 中的 what 函数

overriding the what function in std::exception in c++

我正在尝试覆盖 what 函数以打印我自己的自定义错误消息。

所有的消息都有相同的开头,因此我认为最好能做到以下几点:

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

我的问题如下:

我不太明白如何根据收到的错误打印不同的消息 没有在每个错误 class 中设置一个特殊的 what 函数——这意味着我必须向 IllegalArgument、IllegalCell 和所有其他错误 class 添加一个 what 函数,这在我看来很糟糕,因为它有太多的函数需要维护并持续加班更新。无论如何我可以避免这种情况,并且能够在主要 class - Exception?

中打印不同的消息

您可以将 class 的名称传递给 Exception 构造函数并存储名称:

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") {}
};

如果你不想每次都写默认构造函数,你可以写一个宏来定义你的子异常。


如果您不介意生成名称,另一种选择是使用 typeid(),例如

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

typeid(*this).name() 生成的名称不标准,例如,机智 gcc 我得到 15IllegalArgument,所以这取决于你。