2012-06-27 16 views
5

मेरे पास एक सार आधार वर्ग है और व्युत्पन्न कक्षा में एक फ़ंक्शन को कार्यान्वित करना चाहता हूं। मुझे फिर से व्युत्पन्न कक्षा में फ़ंक्शन घोषित क्यों करना है?एक इंटरफ़ेस को फिर से शुरू करने की आवश्यकता क्यों है?

class base { 
public: 
    virtual int foo(int) const = 0; 
}; 

class derived : public base { 
public: 
    int foo(int) const; // Why is this required? 
}; 

int derived::foo(int val) const { return 2*val; } 

उत्तर

7

मान लें कि व्युत्पन्न-श्रेणी परिभाषा शीर्षलेख में हो सकती है, जबकि इसका कार्यान्वयन स्रोत फ़ाइल में हो सकता है। हेडर आमतौर पर कई स्थानों ("अनुवाद इकाइयों") में शामिल हो जाता है, जिनमें से प्रत्येक स्वतंत्र रूप से संकलित किया जाएगा। यदि आपने ओवरराइड घोषित नहीं किया है, तो संकलक किसी अन्य अनुवाद इकाइयों में इसके बारे में नहीं जान पाएगा।

+0

क्या इसका मतलब यह है कि, यदि मैं व्युत्पन्न कक्षा में फ़ंक्शन को पुन: प्राप्त नहीं करता हूं तो संकलक व्युत्पन्न कक्षा के ओवरराइडिंग कार्यान्वयन की तलाश नहीं करेगा? – Michael

+0

@ माइकल: हाँ, मुझे लगता है कि यह सही है। –

4

एक समारोह बेस कक्षा में शुद्ध virtual बनाने की मंशा है कि व्युत्पन्न वर्ग इसे ओवरराइड और अपने स्वयं के कार्यान्वयन प्रदान करनी चाहिए है।
ध्यान दें कि कक्षा में शुद्ध वर्चुअल फ़ंक्शन की उपस्थिति उस वर्ग को Abstract class बनाता है। सरल शब्दों में कक्षा अधिक ठोस वर्ग बनाने के लिए एक इंटरफ़ेस के रूप में कार्य करती है। कोई सार वर्ग की वस्तुएं नहीं बना सकता है।

यदि आप व्युत्पन्न वर्ग में शुद्ध वर्चुअल फ़ंक्शन को ओवरराइड नहीं करते हैं तो व्युत्पन्न कक्षा में विरासत में बेस क्लास शुद्ध वर्चुअल फ़ंक्शन होता है और यह स्वयं सार तत्व के रूप में भी कार्य करता है। एक बार आपकी व्युत्पन्न कक्षा सार होती है तो इसे तत्काल नहीं किया जा सकता है।
तो ताकि आपकी व्युत्पन्न कक्षा को तत्काल चालू किया जा सके, इसे ओवरराइड करने की आवश्यकता है और इसलिए शुद्ध वर्चुअल फ़ंक्शन घोषित करने की आवश्यकता है।

+0

आप सही हैं। हालांकि, भले ही बेस क्लास अमूर्त नहीं है, अगर मैं कार्यान्वयन को ओवरराइट करना चाहता हूं तो मुझे फ़ंक्शन को फिर से शुरू करने की आवश्यकता है। – Michael

1

It is to override the abstraction of the base class

यदि आप इसे फिर से घोषित नहीं करते हैं, तो आपकी व्युत्पन्न कक्षा भी एक सार वर्ग है। यदि आप करते हैं तो अब आपके पास आधार का एक गैर-सार प्रकार है।

2

आप सोच सकते हैं संकलक मान सकते हैं कि आप derived::foo() के एक कार्यान्वयन प्रदान करने के लिए करने जा रहे हैं, लेकिन derived भी एक अमूर्त वर्ग हो सकता है (और वास्तव में है कि अगर आप न derived में foo() घोषित तुम क्या मिलेगा)

1

क्योंकि पदानुक्रम में अधिक परतें हो सकती हैं।

struct Base { 
    virtual void foo() const = 0; 
    virtual void bar() const = 0; 
}; 

struct SuperBase: Base { 
    virtual void bar() const override; 
}; 

struct Concrete: SuperBase { 
    virtual void foo() const override; 
}; 

यहाँ, SuperBasefoo के लिए एक कार्यान्वयन प्रदान नहीं करता है, इस की जरूरत है किसी भी तरह का संकेत हो।

1

आप शुद्ध आभासी कार्यों के साथ एक वर्ग का दृष्टांत नहीं कर सकते, तो आप अभी भी इस तरह एक वर्ग बना सकते हैं:

class base { 
public: 
    virtual int foo(int) const = 0; 
}; 

class derived : public base { 
public: 
}; 

class very_derived : public derived { 
public: 
    virtual int foo(int) const { return 2; } 
}; 

व्युत्पन्न वर्ग अभी भी एक अमूर्त वर्ग है, यह इसके बाद से instantiated नहीं किया जा सकता है foo ओवरराइड नहीं करता है। कक्षा को तुरंत चालू करने से पहले आपको foo का एक गैर-शुद्ध वर्चुअल संस्करण घोषित करने की आवश्यकता है, भले ही आप तुरंत foo को परिभाषित न करें।

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

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