1

考虑以下代码

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)方法。似乎另一种方法已经消失了。如果我删除了覆盖版本,即声明Ypublic Y : public X{};,那么一切正常。为什么会这样?

4

2 回答 2

5

当派生类定义一个与基类同名的成员时,派生类名称隐藏基类名称。

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

class Y : public X{
public:

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

    void foo(int index){ }
};
于 2012-09-18T13:49:00.107 回答
1

重载适用于在同一范围内定义的名称。所以fooin classY不会重载 class 中的foos X,因为它们是在不同的作用域中定义的。这被非正式地称为“名称隐藏”。要将基类名称拉入派生类,请添加 using 指令:

using X::foo;
于 2012-09-18T14:28:22.153 回答