2014-11-09 7 views
9

विरासत में परेशानी होने के कारण। मुझे नहीं पता कि मैं क्या गलत कर रहा हूं।सी ++ त्रुटि: अमूर्त वर्ग प्रकार की वस्तु की अनुमति नहीं है: शुद्ध वर्चुअल फ़ंक्शन में कोई ओवरराइडर नहीं है

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' दो अलग-अलग फ़ंक्शन हैं। –

उत्तर

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

तो आपको त्रुटि मिल रही है क्योंकि व्युत्पन्न में प्रदर्शन आधार में डिस्प्ले छुपाएगा।

इसी तरह आपका शुद्ध वर्चुअल फ़ंक्शन छिपा होगा i.e संकलक उस मामले का इलाज करेगा क्योंकि बेस क्लास शुद्ध आभासी फ़ंक्शन से संबंधित व्युत्पन्न में कोई फ़ंक्शन परिभाषित नहीं किया गया है। यह एक सार वर्ग भी व्युत्पन्न करेगा।

आशा बातें साफ हैं ...

+0

कक्षा के दायरे के बाहर भी कार्य ओवरलोडिंग संभव है। – 0x499602D2

+0

ओ.के. तो आपको क्या लगता है कि इसका कारण हो सकता है? – ravi

+0

गैर-कॉन्स विधि आधार वर्ग (अलग-अलग कॉन्स-क्वालीफिकेशन की वजह से) में किसी एक को ओवरराइड नहीं करता है, लेकिन चूंकि इसका नाम समान है * यह बेस क्लास में * छुपाता है। चूंकि यह अतिसंवेदनशील नहीं है, व्युत्पन्न वर्ग अमूर्त हो जाता है। – 0x499602D2

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 -qualification में मेल नहीं खाते पर हावी नहीं है। इसलिए Circle अमूर्त हो जाता है क्योंकि उन विधियों शुद्ध आभासी थे; और आप अमूर्त प्रकार की वस्तुएं नहीं बना सकते हैं।

इसे ठीक करने के लिए, बस अपनी दोनों विधियों में const जोड़ें।

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

अगर वे ओवरराइड नहीं करते संकलक आपको एक त्रुटि संदेश के साथ पता चल जाएगा: इसके अलावा, आधार वर्ग से सुनिश्चित करें कि आप सही ढंग से overrided है तरीकों बनाने के लिए, override विनिर्देशक का उपयोग करें।

संबंधित मुद्दे

 संबंधित मुद्दे