क्या 'ओवरराइड' कीवर्ड केवल ओवरराइड वर्चुअल विधि के लिए एक जांच है?


226

जहां तक ​​मैं समझता हूं, overrideC ++ 11 में कीवर्ड की शुरूआत यह सुनिश्चित करने के लिए एक जांच से अधिक कुछ नहीं है कि कार्यान्वित किया जा रहा फ़ंक्शन बेस क्लास में फ़ंक्शन overrideका आईएनजी है virtual

क्या यही है?


50
हां
.

13
हालांकि यह दोहरी जांच नहीं है। यह एकमात्र जाँच है।
निकोस सी।

13
हे, ओवरराइड एक कीवर्ड नहीं है, यह एक व्याकरण चीनी की तरह है। int ओवरराइड = 42; // ठीक है
KAlO2

2
यह अतिरिक्त रूप से पठनीयता में सुधार करता है कि घोषित कार्य को समझा जा सकता है;)
mots_g

5
तो, उह ... C ++ 11 कब पर्याप्त रूप से मानक बन जाएगा कि वे मेरे स्थानीय 4 साल में इस तरह की चीजें सिखाना शुरू कर देंगे? उन्हें कब पता चलेगा ?!
सिनच

जवाबों:


263

यह वास्तव में विचार है। मुद्दा यह है कि आप स्पष्ट हैं कि आपका क्या मतलब है, ताकि एक अन्यथा मूक त्रुटि का निदान किया जा सके:

struct Base
{
    virtual int foo() const;
};

struct Derived : Base
{
    virtual int foo()   // whoops!
    {
       // ...
    }
};

उपरोक्त कोड संकलित करता है, लेकिन वह नहीं है जिसका आपने मतलब हो सकता है (लापता को नोट करें const)। यदि आपने इसके बजाय कहा है virtual int foo() override, तो आपको एक कंपाइलर त्रुटि मिलेगी कि आपका फ़ंक्शन वास्तव में कुछ भी ओवरराइड नहीं कर रहा है।


74
+1: हालांकि, दुर्भाग्य से, यह एक लाल हेरिंग का एक सा है जब लोग सुझाव देते हैं कि नई overrideसुविधा इसे "ठीक" करती है; आपको इसे इस्तेमाल करना याद रखना होगा, ठीक वैसे ही जैसे आपको लिखने के लिए याद रखना चाहिए const;)
लाइटनेस दौड़ ऑर्बिट में

मुझे सिर्फ एहसास हुआ कि explicitकक्षा की परिभाषाएँ इसे C ++ 11 में नहीं बनाती हैं। हुह।
aschepler

1
@aschepler और explicitवर्ग परिभाषा क्या करेगी ? उसके बारे में कभी नहीं सुना।
क्रिश्चियन राऊ

18
@LightnessRacesinOrbit: हाँ, यह मूर्खतापूर्ण प्रमाण नहीं है; हालांकि, (पागलों की तरह लेखन के एक सामान्य नियम को याद overrideहै जब एक यह करने का इरादा रखता है) अधिक होने की संभावना कोने मामलों याद से यानी वहाँ विभिन्न प्रोटोटाइप का काम करता है, लापता की तरह ही अनियमितताओं को कॉपी करने में कोई व्यापकता है constया लेखन charके बजाय int, आदि
legends2k

1
@ लाइट, स्पेसियर का सबसे अच्छा उपयोग मामला इस उत्तरoverride में उल्लिखित है , जो तत्काल से अधिक भविष्य है। उत्तर बताता है कि, विधि के साथ रखें । भविष्य में जब कोई गलती से हस्ताक्षर बदलता है, तो इसकी उपयोगिता में overridevirtual
कमी आती है

35

विकिपीडिया बोली:

ओवरराइड विशेष पहचानकर्ता का मतलब है कि कंपाइलर बेस क्लास (तों) को यह देखने के लिए जांचेगा कि क्या इस सटीक हस्ताक्षर के साथ एक वर्चुअल फ़ंक्शन है। और अगर वहाँ नहीं है, तो कंपाइलर त्रुटि करेगा।

http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final

संपादित करें (उत्तर को थोड़ा सुधारने का प्रयास):

एक विधि को "ओवरराइड" के रूप में घोषित करने का मतलब है कि उस विधि का उद्देश्य आधार वर्ग पर एक (आभासी) विधि को फिर से लिखना है। ओवरराइडिंग विधि में एक ही हस्ताक्षर (कम से कम इनपुट मापदंडों के लिए) होना चाहिए क्योंकि यह विधि फिर से लिखना चाहती है।

यह क्यों आवश्यक है? खैर, निम्नलिखित दो सामान्य त्रुटि मामलों को रोका जाता है:

  1. एक नई विधि में एक प्रकार गलत है। संकलक, इस बात से अनभिज्ञ है कि यह पिछली पद्धति को लिखने का इरादा है, बस इसे एक नई विधि के रूप में कक्षा में जोड़ता है। समस्या यह है कि पुरानी पद्धति अभी भी है, नए को केवल एक अधिभार के रूप में जोड़ा जाता है। इस मामले में, पुरानी पद्धति की ओर सभी कॉल पहले की तरह ही काम करेंगे, बिना किसी व्यवहार में बदलाव के (जो कि पुनर्लेखन का बहुत उद्देश्य होगा)।

  2. सुपरक्लास में विधि को "आभासी" घोषित करना भूल जाता है, लेकिन फिर भी इसे एक उपवर्ग में फिर से लिखने का प्रयास करता है। हालांकि यह स्पष्ट रूप से स्वीकार किया जाएगा, व्यवहार बिल्कुल इरादा नहीं होगा: विधि आभासी नहीं है, इसलिए सुपरक्लास की ओर संकेत के माध्यम से पहुंच नए (उपवर्ग) विधि के बजाय पुराने (सुपरक्लास) विधि को कॉल करेगी।

"ओवरराइड" को जोड़ने से यह स्पष्ट रूप से अलग हो जाता है: इसके माध्यम से, एक कंपाइलर को बता रहा है कि तीन चीजें उम्मीद कर रही हैं:

  1. सुपरक्लास में इसी नाम से एक विधि है
  2. सुपरक्लास में इस विधि को "आभासी" (अर्थात, फिर से लिखे जाने का इरादा) के रूप में घोषित किया गया है
  3. सुपरक्लास में विधि में उप-विधि (पुनर्लेखन विधि) के रूप में एक ही (इनपुट *) हस्ताक्षर है।

यदि इनमें से कोई भी गलत है, तो त्रुटि का संकेत दिया जाता है।

* नोट: आउटपुट पैरामीटर कभी-कभी अलग, लेकिन संबंधित प्रकार का होता है। रुचि के बारे में सहसंयोजक और contravariant परिवर्तनों के बारे में पढ़ें।


31

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


1
+1। हालांकि overrideइस तरह की समस्याओं की खोज करने के लिए एक अच्छा तरीका है, अच्छी इकाई परीक्षण कवरेज भी मदद करनी चाहिए।
मोहभंग हुआ

1
यही कारण है कि मैं उस नए विनिर्देशक के बारे में बहुत उत्साहित हूं। एकमात्र समस्या यह है कि इस सुविधा को पहले से ही लागू किया जाना चाहिए ताकि आधार वर्गों में बदलाव के कारण होने वाली त्रुटियों को रोका जा सके। ;-)
वुल्फ

5

हां, ऐसा है। यह सुनिश्चित करने के लिए एक जांच है कि कोई ओवरराइड की कोशिश नहीं करता है और इसे एक हस्ताक्षर किए गए हस्ताक्षर के माध्यम से गड़बड़ करता है। यहाँ एक विकी पृष्ठ है जो इस बारे में विस्तार से बताता है और इसका संक्षिप्त उदाहरण है:

http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final


2

C ++ 17 मानक ड्राफ्ट

C ++ 17 N4659 मानक ड्राफ्ट पर सभी overrideहिट पर जाने के बाद , पहचानकर्ता को मैं केवल एक ही संदर्भ दे सकता हूं :override

5 यदि किसी वर्चुअल फ़ंक्शन को गुण-निर्दिष्ट ओवरराइड के साथ चिह्नित किया गया है और बेस क्लास के सदस्य फ़ंक्शन को ओवरराइड नहीं करता है, तो प्रोग्राम बीमार है। [ उदाहरण:

struct B {
  virtual void f(int);
};

struct D : B {
  virtual void f(long) override; // error: wrong signature overriding B::f
  virtual void f(int) override;  // OK
}

- अंतिम उदाहरण]

इसलिए मुझे लगता है कि संभवतः गलत कार्यक्रमों को हवा देना वास्तव में एकमात्र प्रभाव है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.