2012-12-14 38 views
153

जहां तक ​​मैं समझता हूं, सी ++ 11 में override कीवर्ड का परिचय यह सुनिश्चित करने के लिए कुछ भी नहीं है कि फ़ंक्शन लागू किया जा रहा है override बेस क्लास में virtual फ़ंक्शन है।क्या 'ओवरराइड' कीवर्ड सिर्फ ओवरराइड वर्चुअल विधि के लिए एक चेक है?

क्या यह है?

+42

हाँ। –

+11

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

+0

@ निकोस अच्छा बिंदु;), – aiao

उत्तर

183

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

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

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

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

+51

+1: हालांकि, दुर्भाग्य से, यह एक लाल हेरिंग का थोड़ा सा है जब लोग सुझाव देते हैं कि नई 'ओवरराइड' सुविधा "इसे ठीक करती है"; आपको इसका उपयोग करना याद रखना होगा, जैसा कि आपको 'const' लिखने के लिए याद रखना चाहिए था); –

+0

मुझे अभी एहसास हुआ कि' स्पष्ट 'वर्ग परिभाषाओं ने इसे C++ 11 में नहीं बनाया है। हुह। – aschepler

+1

@aschepler और 'स्पष्ट' वर्ग परिभाषा क्या करेगी? इसके बारे में कभी नहीं सुना। –

3

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

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

23

विकिपीडिया बोली:: यहाँ एक विकी पेज कि विस्तार से यह बताता है और एक छोटी उदाहराणदर्शक उदाहरण है है

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

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

संपादित करें (एक सा जवाब में सुधार करने के लिए प्रयास):

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

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

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

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

जोड़ना "ओवरराइड" स्पष्ट रूप से इस स्पष्ट रूप से दिखाता:

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

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

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

18

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

+0

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

+0

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