2014-11-09 24 views
9

Gặp sự cố với kế thừa. Tôi không biết mình đang làm gì sai.Lỗi C++: đối tượng của loại lớp trừu tượng không được phép: hàm ảo thuần túy không có ghi đè

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 

và sau đó trong main.cpp, trên dòng chứa "Circle c1(5);" tôi nhận được lỗi:

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()' và 'getArea() const' là hai hàm khác nhau. –

Trả lời

5

chức năng của bạn nên là: -

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

LÝ DO HÀNH VI NÀY: -

Khi bạn tái xác định một hàm trong lớp có nguồn gốc với cùng thông số như trong lớp cơ sở thì đó được gọi là như trọng. Trong khi nếu bạn xác định lại chức năng đó với tham số khác thì nó sẽ là một nỗ lực để sử dụng quá tải từ phía bạn. Nhưng quá tải có thể chỉ trong phạm vi lớp. Vì vậy, trong trường hợp này, hàm lớp cơ sở tương ứng sẽ bị ẩn.

Ví dụ: - Dưới đây là nỗ lực vô ích khi quá tải.

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

Vì vậy, bạn nhận được lỗi khi hiển thị trong nguồn gốc sẽ ẩn hiển thị trong cơ sở.

Tương tự, chức năng ảo thuần túy của bạn sẽ bị ẩn, tức là trình biên dịch xử lý trường hợp đó vì không có hàm nào được xác định trong nguồn gốc tương ứng với lớp cơ sở thuần ảo.Đó sẽ tạo ra một lớp trừu tượng.

Hope điều là tinh thể rõ ràng ...

+0

Quá tải chức năng có thể ở bên ngoài phạm vi lớp học. – 0x499602D2

+0

O.K vậy bạn nghĩ lý do cho điều này có thể là gì? – ravi

+0

Phương thức non-const không ghi đè lên một const trong lớp cơ sở (vì khác nhau về trình độ chuyên môn), nhưng vì nó có cùng tên nó * ẩn * một trong lớp cơ sở. Vì nó không được overriden, lớp dẫn xuất trở nên trừu tượng. – 0x499602D2

0

Bạn quên đặt vòng const cho các chức năng ảo trong lớp dẫn xuất. Viết

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

Vì vậy, trên thực tế trong lớp dẫn xuất bạn khai báo hàm mới ẩn chức năng ảo trong lớp cơ sở có cùng tên.

Ngoài ra, bạn cũng nên khai báo hàm hủy cũng như ảo. Ví dụ

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

Hoặc

class FigureGeometry 
{ 
public: 
    // ... 
    virtual ~FigureGeometry() {} 
}; 
0

getArea()getPerimeter() bạn phương pháp này không ghi đè lên các phương pháp ảo khai báo trong FigureGeometry vì họ không phù hợp trong const -qualification. Do đó Circle trở nên trừu tượng vì các phương thức đó là thuần ảo; và bạn không thể tạo các đối tượng kiểu trừu tượng.

Để khắc phục điều này, chỉ cần thêm const vào cả hai phương pháp của bạn.Ngoài ra, để thực hiện phương pháp chắc chắn rằng bạn đã overrided một cách chính xác từ các lớp cơ sở, sử dụng override specifier:

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

Nếu họ không ghi đè lên các trình biên dịch sẽ cho bạn biết với một thông báo lỗi.

Các vấn đề liên quan