दिलचस्प पोस्ट
एंड्रॉइड पर पोर्ट्रेट मोड में ज़क्सिंग कैमरा PHP में वेब स्क्रैपर को कैसे कार्यान्वित करें? JSON इन्फिनिटी और नाएन को छोड़ दिया; ECMAScript में JSON की स्थिति? मैं कैसे PHP में एक सरणी में एक अल्पविराम सीमांकित स्ट्रिंग विभाजित कर सकते हैं? क्या सिस्टम ऐक्सिट अपवाद को sys.exit () से पकड़े जाने से उठाने को रोकने का एक तरीका है? जावा में छवि को कुशलता से रंग दें कैसे अनुकूलित / एक UIPopoverController शैली गिट 1.7.0 में स्पारस चेकआउट? IntelliJ IDEA में बाहरी पुस्तकालय कैसे जोड़ें? वास्तव में 8192 तत्वों पर लूपिंग करते समय मेरा प्रोग्राम धीमा क्यों है? एंड्रॉइड वेबव्यू में यूट्यूब वीडियो को कैसे रोकें? मुझे कैसे पता चलेगा कि कोई जनरेटर प्रारंभ से खाली है या नहीं? एंड्रॉइड में इंटरनेट से वर्तमान समय कैसे प्राप्त करें पृष्ठभूमिवर्कर का उपयोग कैसे करें? सी ++ में स्थान से अलग किए गए फ़्लोट्स को कैसे पर्स करना है?

सी ++ ओवरलोड संकल्प

निम्नलिखित उदाहरण को देखते हुए, मुझे स्पष्ट रूप से b->A::DoSomething() बजाय b->A::DoSomething() बजाय का उपयोग क्यों करना चाहिए?

क्या संकलक के ओवरलोड संकल्प से यह पता नहीं लगाया जा सकता कि किस पद्धति के बारे में मैं बात कर रहा हूं?

मैं माइक्रोसॉफ्ट वीएस 2005 का उपयोग कर रहा हूं। (ध्यान दें: आभासी उपयोग इस मामले में मदद नहीं करता है।)

 class A { public: int DoSomething() {return 0;}; }; class B : public A { public: int DoSomething(int x) {return 1;}; }; int main() { B* b = new B(); b->A::DoSomething(); //Why this? //b->DoSomething(); //Why not this? (Gives compiler error.) delete b; return 0; } 

वेब के समाधान से एकत्रित समाधान "सी ++ ओवरलोड संकल्प"

दो "अधिभार" समान क्षेत्र में नहीं हैं डिफ़ॉल्ट रूप से, कम्पाइलर केवल जब तक इसे एक नाम मैच नहीं मिलते तब तक सबसे छोटी संभव नाम का क्षेत्र मानता है तर्क मिलान बाद में किया जाता है आपके मामले में इसका अर्थ है कि संकलक B::DoSomething देखता है यह तब तर्क सूची से मेल खाने की कोशिश करता है, जो विफल हो जाता है।

एक समाधान अधिभार को A से B के दायरे से निकालना होगा:

 class B : public A { public: using A::DoSomething; // … } 

ओवरलोड रिज़ॉल्यूशन C ++ के सबसे खराब हिस्सों में से एक है

मूल रूप से कंपाइलर को बी के दायरे में एक नाम "DoSomething (int)" मिल जाता है, देखता है पैरामीटर मेल नहीं खाते, और त्रुटि के साथ बंद हो जाता है।

यह कक्षा बी में ए :: डोजसमिंग का उपयोग करके इसे दूर किया जा सकता है

 class A { public: int DoSomething() {return 0;} }; class B : public A { public: using A::DoSomething; int DoSomething(int x) {return 1;} }; int main(int argc, char** argv) { B* b = new B(); // b->A::DoSomething(); // still works, but... b->DoSomething(); // works now too delete b; return 0; } 

नहीं, यह व्यवहार यह सुनिश्चित करने के लिए मौजूद है कि आप गलती से दूर के आधार वर्गों से वंशानुगत नहीं पकड़े जाते।

इसके चारों ओर जाने के लिए, आपको कम्पाइलर को यह बताने की ज़रूरत है कि बी क्लास में A: DoSomething का उपयोग करके आप किस विधि को कॉल करना चाहते हैं।

इस व्यवहार के त्वरित और आसान अवलोकन के लिए इस लेख को देखें।

व्युत्पन्न वर्ग में एक विधि की उपस्थिति आधार वर्गों में समान नाम (पैरामीटर की परवाह किए बिना) के सभी तरीकों को छुपाता है। इस तरह से समस्याओं से बचने के लिए यह किया जाता है:

 class A {} ; class B :public A { void DoSomething(long) {...} } B b; b.DoSomething(1); // calls B::DoSomething((long)1)); 

बाद में कोई व्यक्ति वर्ग ए बदलता है:

 class A { void DoSomething(int ) {...} } 

अब अचानक:

 B b; b.DoSomething(1); // calls A::DoSomething(1); 

दूसरे शब्दों में, अगर यह इस तरह काम नहीं करता है, तो एक ऐसे क्लास में असंबंधित परिवर्तन जिसे आप नियंत्रित नहीं करते (ए), चुपचाप को प्रभावित कर सकते हैं कि आपका कोड कैसे काम करता है

इसका नाम रिज़ॉल्यूशन के तरीके से कुछ करना है असल में, हम सबसे पहले उस क्षेत्र को खोजते हैं जिसमें नाम आता है, और उसके बाद हम उस दायरे में उस नाम के सभी अधिभार एकत्र करते हैं। हालांकि, आपके मामले में गुंजाइश वर्ग बी है, और कक्षा बी में, B :: DoSomething ए छुपती है :: DOSomething:

3.3.7 नाम छुपाएं [basic.scope.hiding]

… [कटाव] …

3 किसी सदस्य की फ़ंक्शन परिभाषा में, स्थानीय नाम की घोषणा एक ही नाम के साथ वर्ग के सदस्य की घोषणा को छुपाती है; basic.scope.class देखें एक व्युत्पन्न वर्ग ( क्लास। ) में एक सदस्य की घोषणा एक ही नाम के आधार वर्ग के सदस्य की घोषणा को छुपाती है; क्लास देखें। मेम्बरलुकअप

नाम छिपाने के कारण, ए :: डूसमैमिंग को ओवरलोड रिज़ॉल्यूशन के लिए भी नहीं माना जाता है

जब आप एक व्युत्पन्न वर्ग में किसी फ़ंक्शन को परिभाषित करते हैं तो यह सभी वर्गों को उस बेस के साथ बेस क्लास में छुपाता है। यदि बेस क्लास फ़ंक्शन आभासी है और एक संगत हस्ताक्षर है तो व्युत्पन्न क्लास फ़ंक्शन बेस क्लास फ़ंक्शन को भी ओवरराइड करता है। हालांकि, यह दृश्यता को प्रभावित नहीं करता है

आप बेस क्लास फ़ंक्शन को एक उपयोग घोषणा के साथ दिखाई दे सकते हैं:

 class B : public A { public: int DoSomething(int x) {return 1;}; using A::DoSomething; }; 

यह अतिभारित नहीं है! यह छुपा रहा है!

फ़ंक्शन का उपयोग करने के लिए विरासत वृक्ष को खोजते समय, C ++ बिना किसी तर्क के नाम का उपयोग करता है, एक बार इसे किसी भी परिभाषा को बंद हो जाता है, तो तर्कों की जांच करता है। दिए गए उदाहरण में, यह कक्षा बी में बंद हो जाता है। आप जो भी कर सकते हैं, उसके लिए कक्षा बी को इस तरह परिभाषित किया जाना चाहिए:

 class B : public A { public: using A::DoSomething; int DoSomething(int x) {return 1;}; }; 

कार्य समारोह द्वारा उप-क्लास में एक ही नाम के साथ छिपा हुआ है (लेकिन एक अलग हस्ताक्षर के साथ) आप उपयोग कर रहे वक्तव्य का उपयोग करते हुए, ए :: डूसोमिंग ();