C ++纯虚方法

时间:2011-06-03 22:00:25

标签: 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
}

这给了我以下编译错误:

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(),因为派生类没有定义它,这会导致调用Derived::obj.f(0)每个类Base中的定义。

我在这里做错了什么?有没有办法实现这个目标?具体来说,我希望调用obj.f()返回10。

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

感谢。

3 个答案:

答案 0 :(得分:8)

您遇到的问题与纯虚函数正交,与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的{​​{1}}中的函数视为f的一部分。这样,当编译器尝试查找名为Derived的函数时,它会同时找到fDerived::f(int)。然后调用将成功,因为编译器可以确定您尝试使用您列出的代码调用Base::f()

希望这有帮助!

答案 1 :(得分:3)

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

答案 2 :(得分:3)

原因是,f类中定义的Derivedhidesf Base函数。解决方案是添加using。像这样:

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

//  vvvvvvvvvvvvvv
    using Base::f;
};