2013-08-12 9 views
102

मैं सी ++ में एक नौसिखिया हूं। मैं override कीवर्ड पर आया हूं जो हेडर फ़ाइल में उपयोग किया गया है जिस पर मैं काम कर रहा हूं। मुझे पता है, override का वास्तविक उपयोग क्या है, शायद एक उदाहरण के साथ समझना आसान होगा।सी ++ में 'ओवरराइड' कीवर्ड क्या है?

+0

यह भी ध्यान रखें C++ 11 'final' कीवर्ड की शुरुआत की। –

+8

@ जेसे गुड और फिर: 'अंतिम' __also एक कीवर्ड__ नहीं है !!! – zaufi

+1

@zaufi: हाँ, मैंने कुछ नया सीखा। मैंने आपका जवाब +1 किया। –

उत्तर

185

override कीवर्ड दो उद्देश्यों में कार्य करता है: "। यह एक आभासी विधि, कि आधार वर्ग का एक आभासी विधि अधिभावी है कि"

  1. यह कोड सीधे की पाठक से पता चलता
  2. कंपाइलर यह भी जानता है कि यह एक ओवरराइड है, इसलिए यह "जांच" कर सकता है कि आप नए तरीकों को बदल नहीं रहे/जोड़ रहे हैं जो आपको लगता है कि ओवरराइड हैं।

उत्तरार्द्ध व्याख्या करने के लिए:

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


class derived: public base 
{ 
    public: 
    int foo(float x) override { ... do stuff with x and such ... } 
} 

class derived2: public base 
{ 
    public: 
    int foo(int x) override { ... } 
}; 

derived2 में संकलक "प्रकार बदलने के लिए" एक त्रुटि जारी करेगा। override के बिना, अधिकांश संकलक "आप एक ही नाम से वर्चुअल विधि छुपा रहे हैं" के लिए चेतावनी देंगे।

+0

* foo * के लिए फंक्शन हेडर नहीं होना चाहिए * कक्षा * derived2 * में समान होना चाहिए ?? मैंने इसे वीएस2017 के साथ संकलित किया और संकलन त्रुटि मिली। मेरा मतलब है कि * derived2 * * foo's * हेडर होना चाहिए: * int foo (float x) ओवरराइड {...} * –

+8

उम, यह पूरी तरह से बिंदु है, कोड उदाहरण दिखाता है कि त्रुटि का पता लगाने के लिए ओवरराइड का उपयोग कैसे किया जा सकता है! –

+0

मुझे लगता है कि # 3 यह है कि ओवरराइड का उपयोग किया जा सकता है ताकि ओवर-ओवर-ओवरराइड फ़ंक्शन (पैरेंट क्लास/इंटरफ़ेस से संबंधित) को हटाया जा सके (वैकल्पिक नहीं)। यह उपयोगी है अगर सबक्लास कॉलबैक की अपेक्षा कर रहा है लेकिन पुस्तकालय परिवर्तन आदि के कारण यह कभी नहीं होगा। – Hei

4

override एक सी ++ 11 कीवर्ड है जिसका अर्थ है कि एक विधि बेस क्लास से किसी विधि से "ओवरराइड" है। इस उदाहरण पर विचार:

class Foo 
    { 
    public: 
     virtual void func1(); 
    } 

    class Bar : public Foo 
    { 
    public: 
     void func1() override; 
    } 

बी :: func1() हस्ताक्षर बराबर एक :: func1() हस्ताक्षर नहीं है क्योंकि बी :: func1() एक :: func1 पर हावी नहीं होता एक संकलन त्रुटि उत्पन्न हो जाएगा करता है(), यह func1() के बजाय एक नई विधि को परिभाषित करेगा।

+5

सी ++ विनिर्देश के अनुसार, "ओवरराइड" एक "विशेष अर्थ के साथ पहचानकर्ता" है। लेकिन सी # में ऐसी चीजें प्रासंगिक खोजशब्द कहलाती हैं। –

0

विकिपीडिया का कहना है:

विधि अधिभावी, वस्तु उन्मुख प्रोग्रामिंग में, कि एक उपवर्ग या बच्चे कक्षा एक विधि है कि पहले से ही अपने सुपर-क्लास के एक या द्वारा प्रदान की एक विशिष्ट कार्यान्वयन प्रदान करने के लिए अनुमति देता है एक भाषा की सुविधा है अभिभावक वर्ग

विस्तार में, आप एक वस्तु foo एक शून्य() फ़ंक्शन है कि हैलो जब:

class bar : foo { 
    // no functions in here but yet, you can call 
    // bar.hello() 
} 
:

class foo { 
    virtual void hello(); // Code : printf("Hello!"); 
} 

foo का एक बच्चा, यह भी एक नमस्ते() फ़ंक्शन होगा

हालांकि, आप "हैलो बार" प्रिंट करना चाहते हैं! जब हैलो() फ़ंक्शन को एक बार ऑब्जेक्ट से बुलाया जा रहा है। आप ओवरराइड

class bar : foo { 
    virtual void hello() override; // Code : printf("Hello Bar!"); 
} 
+4

आपको सी ++ में ऐसा करने के लिए ओवरराइड पहचानकर्ता की आवश्यकता नहीं है, यह केवल यह लागू करता है कि आप इसे ठीक से कर रहे हैं। – Goose

43

और सभी प्रतिक्रिया के लिए परिशिष्ट के रूप में उपयोग करते हुए ऐसा कर सकते हैं, जानकारी के लिए: overrideएक कीवर्ड, लेकिन एक विशेष पहचानकर्ता की तरह नहीं है! इसका अर्थ केवल वर्चुअल फ़ंक्शंस को घोषित/परिभाषित करने के संदर्भ में है, अन्य संदर्भों में यह केवल एक साधारण पहचानकर्ता है। विवरण के लिए 2.11.2 मानक पढ़ें।

// kate: hl C++11; 
#include <iostream> 

struct base 
{ 
    virtual void foo() = 0; 
}; 

struct derived : base 
{ 
    virtual void foo() override 
    { 
     std::cout << __PRETTY_FUNCTION__ << std::endl; 
    } 
}; 

int main() 
{ 
    base* override = new derived(); 
    override->foo(); 
    return 0; 
} 

आउटपुट:

[email protected] /work/tests $ g++ -std=c++11 -o override-test override-test.cc 
[email protected] /work/tests $ ./override-test 
virtual void derived::foo() 
+3

यह काम करता है (यहां और 'अंतिम' के लिए) क्योंकि आप नियमित पहचानकर्ताओं का उपयोग नहीं कर सकते हैं जहां इन प्रासंगिक कीवर्ड रखा जाएगा। – CTMacUser

+0

क्यों यह प्रतिबंधित नहीं है? –

+2

@ फ़ेरेनकडाका 1. यह क्यों होना चाहिए? 2. अचानक एक नया कीवर्ड जोड़ना (यानी हर जगह इसका उपयोग करने से मना कर देना) पीछे की संगतता को तोड़ देगा। – idmean

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