为什么我无法覆盖虚拟功能?

Les*_*ter 6 c++ polymorphism inheritance overriding constants

我试图覆盖 Vector_container 中的大小函数,但 IDE 告诉我“标记为‘覆盖’的非虚拟成员函数隐藏虚拟成员函数”

class Container {
public:
    virtual double& operator[](int) = 0;     // pure virtual function
    virtual int size() const = 0;            // const member function (§4.2.1)
    virtual ~Container() {}                  // destructor (§4.2.2)
};


class Vector_container : public Container {   // Vector_container implements Container
public:
    Vector_container(int s) : v(s) { }   // Vector of s elements
    ~Vector_container() {}

    double& operator[](int i) override { return v[i]; }
    int size() override { return v.size(); }
private:
    Vector v;
};
Run Code Online (Sandbox Code Playgroud)

但它不是一个虚函数吗?

Pau*_*ton 1

正如其他人提到的,const 的使用改变了函数的签名。我想添加一些更多的知识,以帮助将来的其他人。

当重写 C++ 中的函数时,如果您的编译器支持 C++11 及更高版本,请在函数签名末尾使用override关键字。这将从编译器中产生更多有用的信息。如果虚拟函数具有 override 关键字,编译器可能会导致程序在编译时失败。如果编译器找不到具有相同函数签名的父虚函数来覆盖,就会发生错误。与运行时相比,在编译时捕获错误几乎总是更好。

看起来好像您使用了 override 关键字,因此它可能为您指明了正确的方向。我阐述这一点的主要原因是我希望看到这个问题的其他人意识到您可以在编译时使用该关键字捕获错误的覆盖。

人们在工业中的常见做法是提供带有或不带有const 的基本函数。虽然许多人可能会说这违背了 const 的目的,但在某些情况下您可能需要在非常量函数或非常量对象上调用 const 函数。唯一的其他选择是使用 mutable,我发现很少有 C++ 程序员理解其含义。

简而言之,const 更改了函数的签名,因此只有在 const 签名匹配的情况下才能在子类上重写。

这是一个类似问题的链接,该问题更深入地介绍了 const 和函数签名。它还深入研究了可变常量和按位常量与概念常量。希望这有助于您理解 - C++ 函数语法/原型 - 括号后的数据类型