【问题标题】:Base class methods are not inherited if the child overrides another method with the same name and different signature如果子类覆盖另一个具有相同名称和不同签名的方法,则不会继承基类方法
【发布时间】:2019-08-12 10:07:23
【问题描述】:

首先,我为这个问题的模糊标题道歉。考虑以下示例:

class A {
    public:
        virtual void foo() const = 0;
        void foo(int n) const {
            while(n--)
                foo();
        }
};

class B: public A {
    public:
        void foo() const override {
            std::cout << "B::foo()" << std::endl;
        }
};

int main() {
    auto obj = B{};

    obj.foo();

    obj.foo(10);
}

基本上我想在类A(和任何子类)中有两个版本的方法foo。没有参数的那个必须由孩子定义(因此它被声明为纯的)。但是,具有整数的那个不需要每个孩子都重新定义(因为功能是相同的:调用无参数版本n 次。)

但是上面的代码没有编译,报错如下:

g++ -D_GLIBCXX_DEBUG -std=c++11    example.cpp   -o example
example.cpp: In function ‘int main()’:
example.cpp:31:15: error: no matching function for call to ‘B::foo(int)’
   31 |     obj.foo(10);
      |               ^
example.cpp:21:14: note: candidate: ‘virtual void B::foo() const’
   21 |         void foo() const override {
      |              ^~~
example.cpp:21:14: note:   candidate expects 0 arguments, 1 provided

为什么会这样?我的推理有什么问题?例如,如果我将带有签名 int foo(int) 的方法重命名为子类的 int foo2(int)' and then callfoo2`,一切正常。

【问题讨论】:

  • 这是正确的。重载基类中的隐藏方法。

标签: c++ c++11 inheritance


【解决方案1】:

这就是名称查找的工作方式。当像B这样的派生类有自己的成员函数foo时,它会隐藏其基类的所有foo成员函数,与virtual-ness和函数参数正交,即隐藏重载设置。但是,您可以明确地将它们拉入。在 B 类的 public: 部分中,添加:

using A::foo;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    • 1970-01-01
    • 2013-02-23
    相关资源
    最近更新 更多