为什么我无法重写虚函数?

7

我试图在Vector_container中覆盖size函数,但IDE告诉我:"非虚成员函数标记为'override',隐藏了虚成员函数"

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

但这不是虚函数吗?


5
基类中的虚函数不同,它是const。 - A M
2
通过标记“const”,函数可以进行重载。 - George
3
不相关的内容:容器的 size() 函数应该返回 size_t 而不是 int - ChrisMM
真是让人恼火。编译器正确地识别出了问题并发出了警告(显然,警告被视为错误),但是这个警告太过无用,以至于会让用户感到困惑。如果能在警告中输出“int size() hides int size() const”,那么为了让不知情的用户不浪费半小时纠结问题,需要额外付出多少代价呢? - Damon
我正在使用XCode,先生。 - Lester
添加一个链接到一个类似的问题,该问题更深入地讨论了const和函数签名。希望这可以帮助到您。 - Paul Renton
2个回答

3

这里的const很重要。您的Container声明了一个纯虚的int size() const,而您尝试覆盖int size()。根据我的测试,将您的覆盖声明为const 可以运行


如果我将代码改为 int size() const override { return v.size(); },它会告诉我:“'this' argument to member function 'size' has type 'const Vector', but function is not marked const”。 - Lester
1
@Lester 如果你编写了 Vector::size,那么你应该将其标记为 const - George
哇,谢谢你帮我检查。不知道这里到底发生了什么! :) - Lester
@Lester 没问题,@George 谢谢你的提醒;我的测试假设 Vector 有一个常量大小,因为我用 std::vector 进行了存根。 - nanofarad

1
正如其他人提到的那样,使用const会改变函数的签名。我想再补充一些知识点,以帮助未来的读者。
在C++中重写一个函数时,如果你的编译器支持C++11及以上版本,请在函数签名的末尾使用override关键字。这将为编译器提供更有用的信息。如果虚函数具有override关键字,则编译器可以在编译时使程序失败。如果编译器找不到具有相同函数签名的父虚函数进行覆盖,就会发生错误。通常最好在编译时捕获错误,而不是在运行时。
看起来你已经使用了override关键字,所以它可能指向了正确的方向。我强调这一点的主要原因是我希望看到这个问题的其他人意识到,你可以使用override关键字在编译时捕获错误的覆盖。
在工业界,人们经常使用一个带有和不带有const的基本函数。虽然许多人认为这违背了const的目的,但有几种情况下,你可能需要在非const函数或非const对象上调用const函数。唯一的另一种选择是使用mutable,但我发现很少有C++程序员理解它的含义。
简而言之,const 改变了函数的签名,因此只有在子类中 const 签名匹配时才能被覆盖。
这里有一个类似问题的链接,更深入地讨论了 const 和函数签名。它还涉及到可变和位 const 与概念 const。希望这有助于您的理解 - c++ 函数语法/原型 - 方括号后的数据类型

1
基本上就是这样了。谢谢。 - Lester

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接