我有一个特定的问题,在下面的例子中描述。我的问题是第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;
}
答案 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 );
}
};