2014-06-11 21 views
1

我只是偶然发现了一个编译错误,我想知道为什么发生这种情况。
代码:虚拟功能通过多个接口访问

struct Foo1 
{ 
    virtual int foo() = 0; 
}; 
struct Foo2 : Foo1 
{ 
    virtual int foo(int i) = 0; 
}; 
struct Bar : public Foo2 
{ 
    virtual int foo() { return 0; } 
    virtual int foo(int i) { return i; } 
}; 
int main() { 
    Bar b; 
    Foo2* f2 = &b; 
    b.foo(); 
    //f2->foo(); // this gives an error 
    return 0; 
} 

误差在GCC 4.8.1是

error: no matching function for call to ‘Foo2::foo()’

我很奇怪,为什么编译器无法看到Foo1::foo功能? 我知道我可以通过在Foo2类中添加using Foo1::foo来解决这个问题,但任何人都可以给我一个参考标准,为什么编译器无法自己找到函数?

回答

4

N3797

3.3.10/3的名称隐藏

In a member function definition, the declaration of a name at block scope hides the declaration of a member of the class with the same name; see 3.3.7. The declaration of a member in a derived class (Clause 10) hides the declaration of a member of a base class of the same name. see 10.2.

所以Foo2::foo()隐藏Foo1::foo()

+1

这是正确的答案。这种现象也被称为“名称隐藏”IIRC,基本上声明如果在派生类中存在具有相同名称的声明,则隐藏基类中的声明。这是设计来避免一些“人为的”行为。 –

3

派生类中的foo隐藏foo具有不同基类的签名。

说,你想要的基地重载包括你需要一个using声明添加到Foo2

struct Foo2 : Foo1 
{ 
    using Foo1::foo; 
    virtual int foo(int i) = 0; 
}; 
+2

是正确的,但他也要求提及这一点。 –

+0

@MarcoA .:是的,看到Rakibul的答案。 – sth