2008-08-20 22 views
22

क्या कोई भी कक्षा कक्षा में किसी विशेष विधि की सवारी करने से बचने के लिए सी ++ में किसी भाषा सुविधा या तकनीक से अवगत है?क्या उप-वर्गों में किसी विधि को ओवरराइड होने से रोकने का कोई तरीका है?

class Base { 
public: 
    bool someGuaranteedResult() { return true; } 
}; 

class Child : public Base { 
public: 
    bool someGuaranteedResult() { return false; /* Haha I broke things! */ } 
}; 

भले ही यह आभासी नहीं है, यह अभी भी अनुमति दी है (Metrowerks संकलक मैं उपयोग कर रहा हूँ में कम से कम), तुम सब मिल एक संकलन समय छुपा गैर आभासी विरासत में मिला समारोह एक्स के बारे में चेतावनी है

उत्तर

12

विचारों के एक जोड़े:

  1. अपने कार्य निजी बनाएं।
  2. अपना कार्य वर्चुअल न बनाएं। यह वास्तव में फ़ंक्शन को किसी अन्य परिभाषा द्वारा छायांकित होने से रोकता नहीं है।

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

शुभकामनाएं!

+1

लेकिन फिर हम उस विधि को अन्य कक्षाओं से नहीं बुला सकते हैं। ? – anshulkatta

+6

ध्यान दें कि सी ++ 11 के साथ जोड़ा गया 'अंतिम' विनिर्देशक है: http://stackoverflow.com/a/16906116/1025391 – moooeeeep

0

यदि आप बच्चे के वर्ग को अपने माता-पिता के रूप में संबोधित करते हैं, तो गैर-वर्चुअल फ़ंक्शन पैरेंट क्लास के संस्करण को कॉल करेगा।

अर्थात्:

Parent* obj = new Child(); 
-1

सी ++ विधियां डिफ़ॉल्ट रूप से निजी और अप्रत्याशित हैं।

  • आप एक निजी विधि
  • आप एक गैर virtual विधि

ओवरराइड नहीं कर सकते आप शायद अधिक भार का जिक्र कर रहे हैं ओवरराइड नहीं कर सकते?

+1

हम निजी आभासी कार्यों को ओवरराइड कर सकते हैं। –

2

एक संकलन समय यह चेतावनी के बजाय एक त्रुटि बनाने के लिए अपने संकलक सेटिंग्स छुपा गैर आभासी विरासत में मिला समारोह एक्स

परिवर्तन के बारे में चेतावनी।

0

जब तक आप विधि वर्चुअल नहीं करते हैं, तो बाल वर्ग इसे ओवरराइड नहीं कर सकता है। यदि आप बच्चे वर्गों को इसे कॉल करने से रोकना चाहते हैं, तो इसे निजी बनाएं।

तो डिफ़ॉल्ट रूप से C++ जो आप चाहते हैं वह करता है।

6

लगता है कि आप जो खोज रहे हैं वह जावा भाषा अंतिम कीवर्ड prevents a method from being overridden by a subclass के बराबर है।

others के रूप में यहां suggested है, आप वास्तव में इसे रोक नहीं सकते हैं। साथ ही, ऐसा लगता है कि यह frequently asked question है।

+4

'अंतिम' कीवर्ड सी ++ 11 (http://en.cppreference.com/w/cpp/language/final) द्वारा पेश किया गया है। इसके अलावा मेरे उत्तर पर एक नज़र डालें (http://stackoverflow.com/a/16896559/1025391) एक और उदाहरण के लिए। – moooeeeep

+0

अच्छा, मुझे यह नहीं पता था। संदर्भों के लिए धन्यवाद! –

0

किसी को उप-वर्ग में आपके फ़ंक्शन के समान नाम का उपयोग करने से रोकने के लिए किसी को भी एक समान वैश्विक फ़ंक्शन नाम का उपयोग करने से रोकने के लिए बहुत अलग नहीं है जैसा कि आपने एक लिंक की गई लाइब्रेरी में घोषित किया है।

आप केवल उम्मीद कर सकते हैं कि आपके कोड का उपयोग करने वाले उपयोगकर्ता, और दूसरों के नहीं, यह सावधान रहेंगे कि वे आपके कोड का संदर्भ कैसे देते हैं और वे सही सूचक प्रकार का उपयोग करते हैं या पूरी तरह से योग्यता का उपयोग करते हैं।

2

(ए) मुझे नहीं लगता कि फ़ंक्शन निजी बनाना समाधान है क्योंकि यह व्युत्पन्न कक्षा से बेस क्लास फ़ंक्शन को छुपाएगा। व्युत्पन्न कक्षा हमेशा एक ही हस्ताक्षर के साथ एक नया फ़ंक्शन परिभाषित कर सकती है। (बी) फ़ंक्शन गैर वर्चुअल बनाना एक पूर्ण समाधान नहीं है क्योंकि, यदि व्युत्पन्न वर्ग एक ही फ़ंक्शन को फिर से परिभाषित करता है, तो कोई भी समय बाध्यकारी यानी obj.someFunction() संकलित करके व्युत्पन्न क्लास फ़ंक्शन को कॉल कर सकता है जहां obj एक उदाहरण है व्युत्पन्न वर्ग।

मुझे नहीं लगता कि ऐसा करने का एक तरीका है। साथ ही, मैं व्युत्पन्न कक्षाओं को आधार वर्ग कार्यों को ओवरराइड करने से प्रतिबंधित करने के आपके निर्णय का कारण जानना चाहता हूं।

0

आपके उदाहरण में, कोई फ़ंक्शन ओवरराइड नहीं किया गया है। यह बदले में छिपा हुआ है (यह ओवरलोडिंग का एक प्रकार का अपमानजनक मामला है)। त्रुटि बाल वर्ग कोड में है। जैसा कि सीएसबीएए ने सुझाव दिया है, आप जो भी कर सकते हैं वह आपके कंपाइलर सेटिंग्स को बदल रहा है (यदि संभव हो); यह तब तक ठीक होना चाहिए जब तक कि आप किसी तृतीय पक्ष लाइब्रेरी का उपयोग न करें जो अपने कार्यों को छुपाता है।

1

मुझे लगता है कि संकलक आपको छिपाने के बारे में चेतावनी देता है !! क्या यह वास्तव में ओवरराइड किया जा रहा है?

कंपाइलर आपको चेतावनी दे सकता है, लेकिन रनटाइम पर, पॉइंटर क्लास क्लास विधि को कॉल किया जाएगा यदि सूचक मूल प्रकार के ऑब्जेक्ट को इंगित करता है, चाहे वह उस वस्तु के वास्तविक प्रकार के बावजूद हो।

यह दिलचस्प है। अपने कंपाइलर के लिए एक छोटा स्टैंडअलोन टेस्ट प्रोग्राम बनाने का प्रयास करें।

0

स्पष्टीकरण के लिए, आप में से अधिकांश ने अपने प्रश्न को गलत समझा। वह एक विधि को "ओवरराइड" करने के बारे में नहीं पूछ रहा है, वह पूछ रहा है कि "छिपाने" को रोकने का कोई तरीका है या नहीं। और सरल जवाब यह है कि "कोई नहीं है!"।

यहाँ

जनक वर्ग एक समारोह को परिभाषित करता है एक बार फिर से अपने उदाहरण है: फिर

int foo() { return 1; } 

बाल वर्ग, जनक इनहेरिट एक ही समारोह को परिभाषित करता है (नहीं अधिभावी):

int foo() { return 2; } 

आप यह सभी प्रोग्रामिंग भाषाओं पर कर सकते हैं। इस कोड को संकलन से रोकने के लिए कुछ भी नहीं है (कंपाइलर पर एक सेटिंग को छोड़कर)। आपको जो सबसे अच्छा मिलेगा वह एक चेतावनी है कि आप माता-पिता की विधि को छुपा रहे हैं। यदि आप बच्चे की कक्षा को कॉल करते हैं और foo विधि का आह्वान करते हैं, तो आपको 2 मिल जाएगा। आपने कोड को व्यावहारिक रूप से तोड़ दिया है।

यही वह पूछ रहा है।

0

तकनीकी रूप से आप आभासी कार्यों को ओवरराइड करने से रोक सकते हैं। लेकिन आप कभी भी कभी भी बदलने या जोड़ने में सक्षम नहीं होंगे। वह पूरी मदद नहीं है। फंक्शन लाइट के रूप में कार्य के सामने टिप्पणी का उपयोग करने के लिए बेहतर है।

28

जब आप वर्चुअल विधियों (सी ++ 11 के साथ पेश किए गए) के लिए final विनिर्देशक का उपयोग कर सकते हैं, तो आप इसे कर सकते हैं। मुझे my favorite doc site:

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

अपने उदाहरण के लिए अनुकूलित इस तरह होगा: जब संकलित

class Base { 
public: 
    virtual bool someGuaranteedResult() final { return true; } 
}; 

class Child : public Base { 
public: 
    bool someGuaranteedResult() { return false; /* Haha I broke things! */ } 
}; 

:

$ g++ test.cc -std=c++11 
test.cc:8:10: error: virtual function ‘virtual bool Child::someGuaranteedResult()’ 
test.cc:3:18: error: overriding final function ‘virtual bool Base::someGuaranteedResult()’ 

आप किसी Microsoft संकलक के साथ काम कर रहे हैं, भी sealed कीवर्ड पर एक नजर है ।

+0

मैंने वर्चुअल को हटा दिया और मुझे बेस कॉल फ़ंक्शन के साथ त्रुटि दिखाई दी ... केवल वर्चुअल फ़ंक्शंस के साथ अंतिम कार्य? – AbhimanyuAryan

1

मैं वही खोज रहा था और कल इस [पुराने] प्रश्न पर आया था।

आज मुझे एक साफ सी ++ 11 कीवर्ड मिला: final। मैंने सोचा कि यह अगले पाठकों के लिए उपयोगी हो सकता है।

http://en.cppreference.com/w/cpp/language/final

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

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