【问题标题】:C++ pure virtual methodsC++ 纯虚方法
【发布时间】:2011-09-08 03:39:01
【问题描述】:

考虑这个演示程序:

#include <stdio.h>

class Base
{
public:
    virtual int f(int) =0;
    virtual int f(){ return f(0); }

    virtual ~Base(){ }
};

class Derived : public Base
{
public:
    int f(int i)
    {
        return (10 + i);
    }
};

int main(void)
{
    Derived obj;
    printf("%d\n", obj.f(1));  // This works, and returns 11
    printf("%d\n", obj.f());   // Adding this line gives me the error listed below
}

这给了我以下编译错误:

virtualfunc.cpp: In function ‘int main()’:
virtualfunc.cpp:25:26: error: no matching function for call to ‘Derived::f()’
virtualfunc.cpp:15:9: note: candidate is: virtual int Derived::f(int)

我希望调用obj.f() 会导致调用Base::obj.f(),因为派生类没有定义它,然后根据类Base 中的定义调​​用Derived::obj.f(0)

我在这里做错了什么?有没有办法做到这一点?具体来说,我希望对 obj.f() 的调用返回 10。

(另外请注意,我意识到我可以使用默认参数来解决这个问题,但这段代码只是我问题的一个简明示例,所以请不要告诉我使用默认参数。)

谢谢。

【问题讨论】:

  • f 函数在Derived hides 其他函数中,在Base 中定义。这就是您收到此错误的原因
  • @Kiril Kirov,你赢了——如果你想回答这个问题,我会将其标记为正确。在派生类定义中显式添加using Base::f; 修复了它。谢谢!
  • @raj -- 是的,它似乎是;我道歉。实际上,我筛选了 20 个左右的问题,这些问题没有回答我的问题,也没有遇到过这个问题。
  • @jedwards - 我很高兴,我提供了帮助。我添加了我的答案(:

标签: c++ inheritance pure-virtual


【解决方案1】:

您遇到的问题与纯虚函数正交,并且与 C++ 如何在类层次结构中进行名称解析有关。

当你写作时

obj.f();

C++ 尝试查找名为f 的函数,因此它知道要调用什么。由于objDerived 类型,它从Derived 内部开始并查找名为f 的函数。它最终找到Derived::f(int),即使这个函数有一个参数,C++ 认为这是你试图调用的方法,因此停止查找。然后编译器会注意到您正在尝试不带参数调用它,从而为您提供有关函数调用的错误。

要解决此问题,您需要告诉 C++ 编译器它还需要尝试查找包含在基类中的函数 Base::f()。为此,您可以更改Derived 的定义,如下所示:

class Derived : public Base
{
public:
    int f(int i)
    {
        return (10 + i);
    }

    using Base::f;
};

using Base::f 这一行告诉 C++ 它应该将Base 中名为f 的函数视为Derived 的一部分。这样,当编译器尝试查找名为f 的函数时,它会同时找到Derived::f(int)Base::f()。然后调用将成功,因为编译器可以确定您正在尝试使用您列出的代码调用Base::f()

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    派生类中f(int) 的定义隐藏了您未覆盖的Base::f 名称。您需要做的就是通过在派生类中写入using Base::f;来取消隐藏:

    class Derived : public Base
    {
    public:
    
        using Base::f;   //note this line!
    
        int f(int i)
        {
            return (10 + i);
        }
    };
    

    【讨论】:

    • @Mahesh:这和虚拟机制无关,因为他使用的是派生类型的对象。
    • 我在这里没有看到 virtual 的任何具体用途。
    【解决方案3】:

    原因是,定义的 f(在 Derived 中)hidesf 函数来自 Base 类。解决方法是添加using。像这样:

    class Derived : public Base
    {
    public:
        int f(int i)
        {
            return (10 + i);
        }
    
    //  vvvvvvvvvvvvvv
        using Base::f;
    };
    

    【讨论】:

      猜你喜欢
      • 2011-06-24
      • 1970-01-01
      • 2016-06-23
      • 1970-01-01
      • 2012-04-02
      • 2011-07-10
      • 1970-01-01
      • 2011-01-11
      相关资源
      最近更新 更多