C++结合重载和重写导致奇怪的行为

gex*_*ide 1 c++ overriding overloading

请考虑以下代码

class X{
public:
    virtual void foo(X x){  }
    virtual void foo(int index){ }

};

class Y : public X{
public:

    void foo(int index){ }
};


int main(){
    Y y;
    y.foo(X()); //Error, see below
}
Run Code Online (Sandbox Code Playgroud)

X已经重载了虚foo方法.一个版本需要一个版本,另一个版本X需要一个int.现在,类Y继承X并覆盖该方法foo(int).该方法foo(X)不能被覆盖,它应该保持不变.

但是,Ymain方法和调用中创建类型的对象时foo(X),编译器会抱怨以下内容:

In function ‘int main()’:
error: no matching function for call to ‘Y::foo(X)’
note: candidate is:
note: virtual void Y::foo(int)
note:   no known conversion for argument 1 from ‘X’ to ‘int’
Run Code Online (Sandbox Code Playgroud)

因此,唯一的候选者是被覆盖的foo(int)方法.似乎另一种方法已经消失了.如果我删除了覆盖版本,即声明Ypublic Y : public X{};,那么一切正常.为什么会这样?

Naw*_*waz 5

当派生类定义与基类中的成员具有相同名称的成员时,派生类名称会隐藏基类名称.

在您的情况下,该功能Y::foo 隐藏 X::foo.您需要将其纳入以下范围Y:

class Y : public X{
public:

    using X::foo;  //it brings X::foo into the scope of Y

    void foo(int index){ }
};
Run Code Online (Sandbox Code Playgroud)

  • @gexicide:实际上它并没有违反LSP,因为当你通过指针或对基类*的引用访问派生类*时,所有基类的方法仍然可以照常使用. (3认同)
  • 但现在假设我有不同的重载和不同的可见性(例如,受保护和公共).通过使用`using X :: foo`,我将所有这些内容公开展示到了`Y`的范围,这不是我想要的.如何保留重载方法的可见性? (2认同)