C++ 将重载和覆盖结合起来会导致奇怪的行为

C++ Combining overloading and overriding results in strange behaviour

本文关键字:重载 覆盖 起来 结合 C++      更新时间:2023-10-16

>请考虑以下代码

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
}

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

但是,在 main 方法中创建类型 Y 的对象并调用 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’

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

当派生类定义与基类中的成员同名的成员时,派生类名将隐藏基类名。

在您的情况下,函数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){ }
};
<</div> div class="answers">重

载适用于在同一作用域中定义的名称。所以类 Y 中的foo不会重载类 X 中的foo,因为它们在不同的作用域中定义。这被非正式地称为"名称隐藏"。若要将基类名称提取到派生类中,请添加 using 指令:

using X::foo;