编译器找不到基类中实现的虚函数 [英] Virtual function implemented in base class not being found by compiler

查看:248
本文介绍了编译器找不到基类中实现的虚函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一种情况,看起来编译器没有找到与另一个成员函数同名的虚函数的基类定义/实现。

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 );
}



我使用Visual C ++ 2008.错误消息是:

I'm using Visual C++ 2008. The error message is:


错误C2664:'Derived :: func':无法将参数1从'One'转换为'Two&'

error C2664: 'Derived::func' : cannot convert parameter 1 from 'One' to 'Two &'

我本以为基于类型的分派可以工作,并调用定义的基类函数。如果我添加一个 Derived :: func(One&)它会编译并正确调用,但在我的情况下,该版本的函数可以在基础类和通常派生类不需要自己实现它。我目前正在通过在基类中放置一个不同的命名,非虚函数,转发函数调用导致的问题:

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?

推荐答案

该方法在派生类中。最简单的解决方案是在派生类中添加一个使用声明。

You are hiding the method in the derived class. The simplest solution is to add a using declaration to the derived class.

struct Derived : public Base
{
    using Base::func;
    virtual void func( Two & );
};


$ b < c $ c>标识符在调用 d.func(一)中必须从 Derived 它将在第一个上下文中停止,它在其中找到 func 标识符,在这种情况下它是 Derived :: func 。不执行进一步的查找,编译器只看到 Derived :: func(Two&)

The issue is that when the compiler tries to lookup the func identifier in the call d.func(one) it has to do that from Derived upwards, but it will stop in the first context where it finds the func identifier, which in this case it is Derived::func. No further lookup is performed and the compiler was seeing only the Derived::func( Two& ).

通过使用Base :: func; 指令添加,当编译器看到派生的定义它将所有 Base :: func 声明放入范围,并且会发现有一个 Base: : Derived

By adding the using Base::func; directive, when the compiler sees the Derived definition it brings all of Base::func declarations into scope, and it will find that there is a Base::func( One & ) that was not overridden in Derived.

注释中未覆写的函式:func(One&)如果你通过引用 Base 来调用,那么编译器会发现 func 的重载,并且会调度

Note also that if you were calling through a reference to Base, then the compiler would find both overloads of func and would dispatch appropriately each one to the final overrider.

Derived d;
Base & b = d;
b.func( one ); // ok even without the 'using Base::func;' directive

这篇关于编译器找不到基类中实现的虚函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆