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

时间:2012-09-18 13:43:50

标签: c++ overloading override

考虑以下代码

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)不会被覆盖,它应该保持不变。

但是,在Y方法中创建main类型的对象并调用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{};,那么一切正常。为什么会这样?

2 个答案:

答案 0 :(得分: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){ }
};

答案 1 :(得分:1)

重载适用于在同一范围内定义的名称 。因此,类foo中的Y不会使类foo中的X重载,因为它们在不同的范围内定义。这被非正式地称为“名字隐藏”。要将基类名称拉入派生类,请添加using指令:

using X::foo;