2014-11-09 96 views
9

繼承有問題。我不知道我在做什麼錯。C++錯誤:不允許抽象類類型的對象:純虛函數沒有覆蓋

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 
+0

'getArea()'和'getArea()const'是兩個不同的函數。 – 2014-11-09 05:15:56

回答

5

你的職能應該是: -

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

所以你會得到錯誤,因爲在派生中顯示會隱藏顯示在基地。

類似地,您的純虛函數將被隱藏,即編譯器會將該情況視爲由於在派生函數中沒有定義對應於基類純虛函數的函數。這將導致派生出一個抽象類。

希望事情都一清二楚......

+0

函數重載也可能在類作用域之外。 – 0x499602D2 2014-11-09 06:01:54

+0

O.K所以你認爲這可能是什麼原因? – ravi 2014-11-09 06:03:28

+0

非const方法不會覆蓋基類中的const方法(因爲不同的const限定),但由於它具有相同的名稱,所以*隱藏*基類中的一個。由於它沒有被覆蓋,派生類變得抽象。 – 0x499602D2 2014-11-09 06:06:01

0

你忘了把預選賽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() {} 
}; 
0

getArea()getPerimeter()方法不覆蓋FigureGeometry聲明,因爲他們不const企業資質相匹配的虛擬方法。因此Circle變得抽象,因爲這些方法是純虛擬的;並且您不能創建抽象類型的對象。

要解決這個問題,只需將const添加到您的兩個方法中即可。此外,爲了使從基類確認你已經正確overrided方法,使用override符:

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

如果不重寫編譯器將讓你知道有一個錯誤消息。

相關問題