编译器找不到基类中实现的虚函数
我遇到了一种情况,编译器似乎找不到与另一个成员函数同名的虚拟函数的基类定义/实现。
struct One {};
struct Two {};
struct Base
{
virtual void func( One & );
virtual void func( Two & ) = 0;
};
struct Derived : public Base
{
virtual void func( Two & );
};
void Base::func( One & )
{}
void Derived::func( Two & )
{}
// elsewhere
void this_fails_to_compile()
{
One one;
Derived d;
d.func( one );
}
我使用的是 Visual C++ 2008。错误消息是:
错误 C2664:“Derived::func”:无法将参数 1 从“One”转换为“Two &”
我本以为基于类型的调度可以工作并调用定义的基类函数。如果我添加一个 Derived::func( One & )
它确实会编译并被正确调用,但在我的情况下,该版本的函数可以在基类中完成,通常派生类不会不需要自己实现。我目前正在解决这个问题,方法是在基类中放置一个不同名称的非虚拟函数,该函数将调用转发给导致问题的函数:
// not virtual, although I don't think that matters
void Base::work_around( One & one )
{
func( one );
}
这可以工作,但显然不太理想。
我在这里缺少什么继承和/或名称隐藏规则?
I've got a situation where it seems like the compiler isn't finding the base class definition/implementation of a virtual function with the same name as another member function.
struct One {};
struct Two {};
struct Base
{
virtual void func( One & );
virtual void func( Two & ) = 0;
};
struct Derived : public Base
{
virtual void func( Two & );
};
void Base::func( One & )
{}
void Derived::func( Two & )
{}
// elsewhere
void this_fails_to_compile()
{
One one;
Derived d;
d.func( one );
}
I'm using Visual C++ 2008. The error message is:
error C2664: 'Derived::func' : cannot convert parameter 1 from 'One' to 'Two &'
I would have thought that the type based dispatch would work and call the defined base class function. If I add a Derived::func( One & )
it does compile and get called correctly, but in my situation, that version of the function can be done in the base class and usually derived classes don't need to implement it themselves. I'm currently working around it by putting a differently named, non-virtual function in the base class that forwards the call to function causing the problem:
// not virtual, although I don't think that matters
void Base::work_around( One & one )
{
func( one );
}
That works but is obviously less than ideal.
What inheritance and/or name-hiding rule am I missing here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您将
func(One&)
函数隐藏在Derived
中。您可以使用完全限定名称:You hide
func(One&)
function inDerived
. You could use fully qualified name:您将该方法隐藏在派生类中。最简单的解决方案是向派生类添加 using 声明。
问题是,当编译器尝试在调用
d.func(one)
中查找func
标识符时,它必须从Derived
执行此操作向上,但它将在找到func
标识符的第一个上下文中停止,在本例中为Derived::func
。没有执行进一步的查找,编译器只看到Derived::func( Two& )
。通过添加
using Base::func;
指令,当编译器看到Derived
定义时,它将所有Base::func
声明引入作用域,它会发现有一个Base::func( One & )
没有在Derived
中被覆盖。另请注意,如果您通过对
Base
的引用进行调用,则编译器将找到func
的两个重载,并将每个重载适当地分派给最终重写器。You are hiding the method in the derived class. The simplest solution is to add a using declaration to the derived class.
The issue is that when the compiler tries to lookup the
func
identifier in the calld.func(one)
it has to do that fromDerived
upwards, but it will stop in the first context where it finds thefunc
identifier, which in this case it isDerived::func
. No further lookup is performed and the compiler was seeing only theDerived::func( Two& )
.By adding the
using Base::func;
directive, when the compiler sees theDerived
definition it brings all ofBase::func
declarations into scope, and it will find that there is aBase::func( One & )
that was not overridden inDerived
.Note also that if you were calling through a reference to
Base
, then the compiler would find both overloads offunc
and would dispatch appropriately each one to the final overrider.