2016-10-08 7 views
22

पिछले हफ्तों में कुछ मेरे दिमाग को वर्चुअल और ओवरराइड के बारे में बता रहा है। मैंने सीखा है कि जब आप वर्चुअल फ़ंक्शन के साथ विरासत करते हैं तो आपको virtual जोड़ना होगा ताकि संकलक सही कार्य की खोज कर सकें। बाद में मैंने यह भी सीखा कि सी ++ 11 में एक नया कीवर्ड है - ओवरराइड। अब मैं थोड़ा उलझन में हूँ; क्या मुझे अपने प्रोग्राम में वर्चुअल और ओवरराइड कीवर्ड दोनों का उपयोग करने की आवश्यकता है, या उनमें से केवल एक का उपयोग करना बेहतर है?आभासी? ओवरराइड? अथवा दोनों? सी ++

अपने आप व्याख्या करने के लिए - मैं क्या मतलब है की कोड उदाहरण:

class Base 
{ 
public: 
    virtual void print() const = 0; 
    virtual void printthat() const = 0; 
    virtual void printit() const = 0; 
}; 

class inhert : public Base 
{ 
public: 
    // only virtual keyword for overriding. 
    virtual void print() const {} 

    // only override keyword for overriding. 
    void printthat() const override {} 

    // using both virtual and override keywords for overriding. 
    virtual void printit() const override {} 
}; 

सबसे अच्छा तरीका क्या है?

+2

जब भी आप किसी विधि को ओवरराइड करना चाहते हैं तो आपको 'ओवरराइड' कीवर्ड का उपयोग करना चाहिए। इस तरह, अगर आप व्युत्पन्न वर्ग में नाम गलत टाइप, तो आपको एक त्रुटि कह मिल जाएगा वहाँ था कोई तरीका – Eric

+2

ओवरराइड करने के लिए मिल गया (http [ 'ओवरराइड' कीवर्ड सिर्फ एक ओवरराइड आभासी विधि के लिए एक जांच है?]: // stackoverflow.com/questions/13880205/is-the-override-keyword-just-a-check-for-a-overriden-virtual-method) – Solarflare

+1

एक और दिलचस्प सवाल यह है कि "क्या होता है यदि मैं वर्चुअल के बिना ओवरराइड का उपयोग करता हूं" – Eric

उत्तर

42

जब आप किसी फ़ंक्शन को ओवरराइड करते हैं तो आपको तकनीकी रूप से virtual या override लिखने की आवश्यकता नहीं होती है।

मूल बेस क्लास घोषणा को वर्चुअल के रूप में चिह्नित करने के लिए कीवर्ड virtual की आवश्यकता होती है।

व्युत्पन्न कक्षा में फ़ंक्शन बेस क्लास फ़ंक्शन के रूप में ¹same प्रकार होने के माध्यम से वर्चुअल है।

हालांकि, override एक संकलन त्रुटि उत्पन्न करके बग से बचने में मदद कर सकता है जब इच्छित ओवरराइड तकनीकी रूप से ओवरराइड नहीं होता है। जैसे कि फ़ंक्शन प्रकार बिल्कुल बेस क्लास फ़ंक्शन की तरह नहीं है। या कि बेस क्लास का रखरखाव उस कार्य के प्रकार को बदलता है, उदा। एक डिफ़ॉल्ट तर्क जोड़ना।

उसी तरह, व्युत्पन्न वर्ग में एक virtual कीवर्ड सुनिश्चित समारोह अब भी है आगे व्युत्पन्न वर्ग में आभासी है कि द्वारा, इस तरह के एक बग अधिक सूक्ष्म बना सकते हैं।

तो सामान्य सलाह है,

  • आधार वर्ग समारोह घोषणा के लिए उपयोग virtual
    यह तकनीकी रूप से आवश्यक है।

  • व्युत्पन्न वर्ग 'ओवरराइड के लिए override (केवल) का उपयोग करें।
    यह रखरखाव में मदद करता है।

उदाहरण:

struct Base { virtual void foo() {} }; 
struct Derived: Base { void foo() override {} }; 

नोट्स:
¹ सी ++ covariant कच्चे सूचक और कच्चे संदर्भ परिणामों का समर्थन करता है। कॉन्वर्सिस के साथ ओवरराइड का प्रकार बिल्कुल वही नहीं है। यह सिर्फ एक संगत प्रकार है।

+3

से cppreference (http://en.cppreference.com/w/cpp/language/virtual): "अगर कुछ सदस्य कार्य vf को कक्षा बेस में वर्चुअल के रूप में घोषित किया जाता है, और कुछ क्लास व्युत्पन्न, जो व्युत्पन्न होता है, सीधे या परोक्ष रूप से बेस से, एक ही नाम पैरामीटर प्रकार की सूची के साथ सदस्य समारोह के लिए एक घोषणा (लेकिन वापसी प्रकार) सीवी-क्वालिफायर रेफरी-क्वालिफायर फिर कक्षा व्युत्पन्न में इस समारोह भी आभासी है (कीवर्ड वर्चुअल का उपयोग इसकी घोषणा में किया जाता है या नहीं) और बेस :: vf ओवरराइड करता है (चाहे शब्द ओवरराइड का उपयोग इसकी घोषणा में किया गया हो)। " – solstice333

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