如果我引用基数 class 捕获异常,为什么我的异常会被切成基数 class?

Why is my exception sliced to base class if I catch it with reference to base class?

所以我写了一个小的C++ class如下:

class bad_hmean : public std::logic_error {
    const char *nature_;
    char *what_;

public:
    bad_hmean(const char *fname);

    ~bad_hmean() { delete[] what_; }

    const char *what() { return what_; }
};

inline bad_hmean::bad_hmean(const char *fname):nature_("BAD HARMONIC MEAN VALUES"), std::logic_error("BAD HARMONIC MEAN VALUES")
{
    int len = strlen(fname) + strlen(nature_)+3;
    what_ = new char [len];
    strcpy(what_, fname);
    strcat(what_, ": ");
    strcat(what_, nature_);
}

而且我已经尝试在以下主要内容中对其进行测试:

void fun1() { throw bad_hmean(__func__); }

int main()
{
    try
    {
        fun1();
    } catch(std::exception& e)
    {
        std::cout << e.what();
    }
}

当我 运行 它时,我遇到了一个我无法解决的问题。即使我按值抛出异常并按引用捕获它,切片仍然会发生,因为我的代码的输出是:BAD HARMONIC MEAN VALUES。 但是如果我捕获异常作为对 bad_hmean 的引用,输出就是我想要的: fun1:谐波平均值不佳

有谁知道为什么会这样?

bad_hmean 没有 覆盖 what() 正确。它应该匹配基classwhat的签名为:

const char *what() const noexcept { return what_; }
//                 ^^^^^ ^^^^^^^^

顺便说一句:最好使用 override specifier(自 C++11 起)以确保该函数覆盖基类 class 的虚函数。例如

const char *what() const noexcept override { return what_; }