2014-06-11 20 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