C++纯虚拟方法

C++ pure virtual methods

本文关键字:方法 虚拟 C++      更新时间:2023-10-16

考虑一下这个演示程序:

#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("%dn", obj.f(1));  // This works, and returns 11
    printf("%dn", 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。

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

谢谢。

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

当你写

obj.f();

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

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

希望这能有所帮助!

原因是,定义的f(在Derived中)hides fBase类起作用。解决方案是添加using。像这样:

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

派生类中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);
    }
};