C++纯虚方法

jed*_*rds 5 c++ inheritance pure-virtual

考虑这个演示程序:

#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
}
Run Code Online (Sandbox Code Playgroud)

这给了我以下编译错误:

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)
Run Code Online (Sandbox Code Playgroud)

我希望调用obj.f()会导致调用,Base::obj.f()因为派生类没有定义它,这将导致Derived::obj.f(0)对类Base中的定义进行调用.

我在这做错了什么?有没有办法实现这个目标?具体来说,我想要obj.f()回复10.

(另请注意,我意识到我可以使用默认参数来解决此问题,但此代码只是我问题的简明示例,因此请不要告诉我使用默认参数.)

谢谢.

tem*_*def 8

您遇到的问题与纯虚函数正交,与C++在类层次结构中的名称解析有关.

当你写作

obj.f();
Run Code Online (Sandbox Code Playgroud)

C++尝试查找名为的函数,f以便知道要调用的内容.由于obj是类型Derived,它从内部开始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;
};
Run Code Online (Sandbox Code Playgroud)

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

希望这可以帮助!

  • 这个解释非常有用 - 非常感谢你. (2认同)

Kir*_*rov 3

原因是,f(在Derived)类中定义了hides函数。解决办法是添加. 像这样:fBaseusing

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

//  vvvvvvvvvvvvvv
    using Base::f;
};
Run Code Online (Sandbox Code Playgroud)