C++ 错误:不允许抽象类类型的对象:纯虚函数没有覆盖器

Posted

技术标签:

【中文标题】C++ 错误:不允许抽象类类型的对象:纯虚函数没有覆盖器【英文标题】:C++ error: object of abstract class type is not allowed: pure virtual function has no overrider 【发布时间】:2014-11-09 05:08:00 【问题描述】:

继承有问题。我不知道我做错了什么。

FigureGeometry.h

    #ifndef FIGUREGEOMETRY
#define FIGUREGEOMETRY

static const float PI = 3.14159f;

class FigureGeometry


public:
    virtual float getArea() const = 0;
    virtual float getPerimeter() const = 0;
;

#endif

Circle.h

    #ifndef CIRCLE
#define CIRCLE

#include "FigureGeometry.h"

class Circle:public FigureGeometry

    float radius;
public:
    Circle(float theRadius)
    
        radius = theRadius;
    
    float getRadius() return radius;
    float getArea() return getRadius() * getRadius() * PI;
    float getPerimeter() return getRadius() * 2 * PI;
;

#endif

然后在 main.cpp 中,在包含 "Circle c1(5);" 的行上我得到错误:

21  IntelliSense: object of abstract class type "Circle" is not allowed:
            pure virtual function "FigureGeometry::getArea" has no overrider
            pure virtual function "FigureGeometry::getPerimeter" has no overrider   c:\Users\moog\Documents\Visual Studio 2012\Projects\data structures 3\data structures 3\main.cpp    9   9   data structures 3

【问题讨论】:

getArea()getArea() const 是两个不同的函数。 【参考方案1】:

你的功能应该是:-

float getArea() const return getRadius() * getRadius() * PI;
float getPerimeter() const return getRadius() * 2 * PI;

这种行为的原因:-

当您在派生类中使用与基类中相同的参数重新定义函数时,这称为覆盖。 然而,如果您使用不同的参数重新定义该函数,那么它将尝试从您这边使用重载。但是重载只能在类范围内进行。因此,在这种情况下,相应的基类函数将被隐藏。

例如:- 下面是对重载的徒劳尝试。

class Base

public:
   virtual void display () const;
;

class Derived 

public:
   virtual void display ();
;

int main()

    const Derived d;
    d.display();           //Error::no version defined for const....

所以你得到了错误,因为在派生中显示会隐藏在基础中的显示。

同样,您的纯虚函数将被隐藏,即编译器将这种情况视为派生中没有定义与基类纯虚函数相对应的函数。这将使派生也成为抽象类。

希望事情一清二楚...

【讨论】:

类范围之外的函数重载也是可能的。 好吧,你认为这可能是什么原因? 非常量方法不会覆盖基类中的 const 方法(因为不同的 const 限定),但由于它具有相同的名称,它隐藏一个在基类中。由于它没有被覆盖,派生类变成了抽象类。 到目前为止一切都很好......但这就是我要问的为什么它隐藏了???只是因为同名。我认为具有相同名称的函数和具有 const 的函数是重载的良好候选者......不是吗??? 请尝试编译上面的示例...如果允许跨类范围重载,它应该可以正确编译...请给我适当的理由说明为什么它没有编译【参考方案2】:

您的getArea()getPerimeter() 方法不会覆盖FigureGeometry 中声明的虚方法,因为它们在const-qualification 中不匹配。因此Circle 变得抽象,因为这些方法是纯虚拟的;而且你不能创建抽象类型的对象。

要解决此问题,只需将const 添加到您的两个方法中即可。此外,为确保您已正确覆盖基类中的方法,请使用 override 说明符:

float getArea() const override;
float getPerimeter() const override;

如果它们不覆盖编译器,编译器将通过错误消息通知您。

【讨论】:

【参考方案3】:

您忘记在派生类中为这些虚函数放置限定符const。写

float getArea() const return getRadius() * getRadius() * PI;
float getPerimeter() const return getRadius() * 2 * PI;

所以实际上你在派生类中声明了新函数,这些新函数在基类中隐藏了同名的虚函数。

你也应该将析构函数声明为虚拟的。例如

class FigureGeometry

public:
    // ...
    virtual ~FigureGeometry() = default;
;

或者

class FigureGeometry

public:
    // ...
    virtual ~FigureGeometry() 
;

【讨论】:

以上是关于C++ 错误:不允许抽象类类型的对象:纯虚函数没有覆盖器的主要内容,如果未能解决你的问题,请参考以下文章

纯虚函数,抽象类

抽象类类型...不允许,纯虚函数不被覆盖

C++纯虚函数和抽象类

C++ 纯虚函数和抽象类

C++ 纯虚函数和抽象类

C++面向对象:C++ 接口(抽象类)