在编译器中找不到基类中实现的虚函数

时间:2010-09-09 15:47:19

标签: c++ inheritance function virtual

我的情况似乎是编译器没有找到与另一个成员函数同名的虚函数的基类定义/实现。

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

虽然有效,但显然不太理想。

我在这里缺少什么继承和/或名称隐藏规则?

2 个答案:

答案 0 :(得分:18)

您正在将方法隐藏在派生类中。最简单的解决方案是在派生类中添加using声明。

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

问题是当编译器尝试在调用func中查找d.func(one)标识符时,它必须从Derived向上执行,但它将在第一个上下文中停止它找到func标识符,在这种情况下它是Derived::func。不再执行查找,编译器只看到Derived::func( Two& )

通过添加using Base::func;指令,当编译器看到Derived定义时,它会将所有Base::func声明带入范围,并且会发现存在Base::func( One & )Derived中未被覆盖。

另请注意,如果您通过对Base的引用进行调用,那么编译器将找到func的两个重载,并且会将每个重载适当地分配给最终的覆盖器。

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

答案 1 :(得分:3)

您在func(One&)隐藏Derived功能。您可以使用完全限定名称:

d.Base::func( one );