2016-02-13 55 views
0

我有一個特定的問題,這在下面的例子中描述。我的問題是行號34(註釋之一):爲什麼這行給我錯誤信息?C++ 11已實現的接口方法不可用。爲什麼?

test.cpp: In function ‘int main()’: 
test.cpp:34:13: error: no matching function for call to ‘C::func(int)’ 
    c.func(33); // Line 34 
     ^
test.cpp:23:24: note: candidate: virtual void C::func(int, int) 
    public : virtual void func(int x, int y) override 
        ^
test.cpp:23:24: note: candidate expects 2 arguments, 1 provided 

C類擴展了B類,B類實現了方法func(int)。但爲什麼不提供這種方法?如果我將C投給A,爲什麼可以使用?

#include <cstdio> 


class A 
{ 
    public : virtual void func(int x) = 0; 
}; 


class B : public A 
{ 
    public : virtual void func(int x, int y) = 0; 

    public : virtual void func(int x) override 
    { 
     func(x, 0); 
    } 
}; 


class C : public B 
{ 
    public : virtual void func(int x, int y) override 
    { 
     printf("x: %d y:%d\n", x, y); 
    } 
}; 


int main() 
{ 
    C c; 
    c.func(4, 6);  
    c.func(33);  // Line 34 

    A* a = &c; 
    a -> func(33); 

    return 0; 
} 

回答

2

這是範圍問題......在C方法func定義類,因此編譯器顯然不試圖找到在上層階級的方法超載......爲了讓編譯器的提示其方法是在你的興趣,你可以使用語法:

c.B::func(33); 

您也可以儘量避免通過給這兩個重載不同的名稱問題...

2

詳細的說明是存在的:https://isocpp.org/wiki/faq/strange-inheritance#hiding-rule

在這種情況下,無關緊要func是虛擬的。事實是,C :: func(int,int)隱藏了B :: func(int)而不是重載它。

您需要在C的作用域中帶回B :: func(int),以便您可以將它與C對象的實例一起使用。這樣,在C的範圍內將會有兩個重載。

如果你的編譯器支持使用:

class C : public B 
{ 
    public : 
    using B::func; 
    virtual void func(int x, int y) override 
    { 
     printf("x: %d y:%d\n", x, y); 
    } 
}; 

如果你的編譯器不:

class C : public B 
{ 
    public : 
    virtual void func(int x) { B::func(x); } 
    virtual void func(int x, int y) override 
    { 
     printf("x: %d y:%d\n", x, y); 
    } 
}; 
相關問題