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

标签 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。错误信息是:

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

我原以为基于类型的调度会起作用并调用定义的基类函数。如果我添加一个 Derived::func(One & ) 它确实编译并被正确调用,但在我的情况下,该版本的函数可以在基类中完成,通常派生类不会'不需要自己实现。我目前正在通过在基类中放置一个不同名称的非虚拟函数来解决它,该函数将调用转发给导致问题的函数:

// not virtual, although I don't think that matters
void Base::work_around( One & one )
{
    func( one );
}

这可行,但显然不太理想。

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

最佳答案

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

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

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

通过添加 using Base::func; 指令,当编译器看到 Derived 定义时,它会将所有 Base::func声明进入作用域,它会发现有一个 Base::func( One & )Derived 中没有被覆盖。

还请注意,如果您通过对 Base 的引用进行调用,那么编译器将找到 func 的两个重载,并将每个重载适本地分派(dispatch)给最终的覆盖器。

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

关于c++ - 编译器找不到在基类中实现的虚函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3678197/

相关文章:

c++ - 如何判断 OpenMP 是否适用于我的 C++ 程序

c# - 使用泛型和 'new' 修饰符隐藏父成员时的 C# 继承问题

c# - 只允许为特定类实现接口(interface)

javascript - 尝试在 javascript 中运行一个简单的初学者函数,但未正确返回

javascript - 如何关闭通过另一个函数的 polyfill 生成的 showModalDialog() ?

c++ - 为什么函数有时无法运行?

c++ - 如何在 C++ 中实现垃圾回收

c++ - 如何重用 ostringstream?

java - 通过 OBJECTS 与 INHERITANCE 访问方法

function - Lua:函数表