C ++ 11已实现的接口方法不可用。为什么?

时间:2016-02-13 12:36:01

标签: c++ c++11 interface

我有一个特定的问题,在下面的例子中描述。我的问题是第34行(注释一个):为什么这行给我错误信息?

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 个答案:

答案 0 :(得分:2)

这是范围问题...在类C中定义方法func,因此编译器显然不会尝试在上层类中找到方法的重载...给编译器一个提示您可以使用哪种方法的提示:

c.B::func(33);

你也可以尝试通过给这两个重载提供不同的名称来避免这个问题......

答案 1 :(得分:2)

详细解释如下:https://isocpp.org/wiki/faq/strange-inheritance#hiding-rule

在这种情况下,无论函数是虚拟的还是无关紧要的。事实是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 );
    }
};