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

发布于 2024-09-18 06:48:27 字数 939 浏览 9 评论 0原文

我遇到了一种情况,编译器似乎找不到与另一个成员函数同名的虚拟函数的基类定义/实现。

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

总攻大人 2024-09-25 06:48:32

您将 func(One&) 函数隐藏在 Derived 中。您可以使用完全限定名称:

d.Base::func( one );

You hide func(One&) function in Derived. You could use fully qualified name:

d.Base::func( one );
等往事风中吹 2024-09-25 06:48:31

您将该方法隐藏在派生类中。最简单的解决方案是向派生类添加 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 的两个重载,并将每个重载适当地分派给最终重写器。

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

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

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& ).

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.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文