2010-01-29 12 views
21

सी ++ में, बेस क्लास का सदस्य फ़ंक्शन उसी नाम, के व्युत्पन्न क्लास फ़ंक्शन द्वारा ओवरराइड किया जाएगा, भले ही इसका प्रोटोटाइप (पैरामीटर 'गिनती, प्रकार और स्थिरता) अलग हो? मुझे लगता है कि यह एक मूर्ख सवाल है, क्योंकि कई वेबसाइटें कहती हैं कि ऐसा होने के लिए फ़ंक्शन प्रोटोटाइप समान होना चाहिए; लेकिन नीचे कोड संकलित क्यों नहीं करता है? विरासत का यह एक बहुत ही साधारण मामला है, मुझे विश्वास है।सी ++ विरासत और फ़ंक्शन ओवरराइडिंग

#include <iostream> 
using std::cout; 
using std::endl; 

class A {}; 
class B {}; 

class X 
{ 
public: 
    void spray(A&) 
    { 
     cout << "Class A" << endl; 
    } 
}; 

class Y : public X 
{ 
public: 
    void spray(B&) 
    { 
     cout << "Class B" << endl; 
    } 
}; 

int main() 
{ 
    A a; 
    B b; 
    Y y; 

    y.spray(a); 
    y.spray(b); 

    return 0; 
} 

जीसीसी फेंकता

error: no matching function for call to `Y::spray(A&)' 
note: candidates are: void Y::spray(B&) 
+0

सी ++ एफएक्यू जो एक ही मुद्दे के बारे में कहता है, एक विस्तृत स्पष्टीकरण के लिए अगर किसी को इसकी आवश्यकता होती है :) http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq- 23.9 – legends2k

+1

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

+0

@ लिटब: स्पष्टीकरण के लिए धन्यवाद! मुझे लगता है कि 'प्रोटोटाइप' यहां उपयुक्त शब्द है, मैंने इसे प्रश्न में बदल दिया है :) – legends2k

उत्तर

28

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

using X::spray; 
+0

स्पष्टीकरण के लिए धन्यवाद, जिसने इसे स्पष्ट किया। यह तब काम करता है जब मैं यहां उपयोग निर्देश जोड़ता हूं। लेकिन जब मैं एक्स में स्प्रे (int) में स्प्रे हस्ताक्षर बदलता हूं और वाई में स्प्रे (फ्लोट) बदलता हूं और y.spray (1) पर कॉल करता हूं; और y.spray (1.0f); यह निर्देश का उपयोग किए बिना काम करता है। कैसे? – legends2k

+2

वाह क्षमा करें, मेरा बुरा, यह अभी भी वाई के स्प्रे (फ्लोट) को देख रहा है, जब मैं y.spray (1) करता हूं; यह int अंतर्निहित फ्लोट करने के लिए int बनाता है। – legends2k

+2

यह उन उत्तरों में से एक है जो अपने स्वयं के विशेष प्रश्न के योग्य हैं, जो खोज पाउडर के साथ तैयार किए गए हैं ताकि लोग इसे बेहतर पा सकें। – Wug

10

ऐसा 'छुपा' कहा जाता है: Y::spray छुपाता X::spray। जोड़ें निर्देशों का उपयोग:

class Y : public X 
{ 
public: 
    using X::spray; 
    // ... 
}; 
5

कक्षा स्कोप कर रहे हैं और एक वर्ग के दायरे अपनी मूल में नीडिंत है। आपके पास अन्य नेस्टेड स्कॉप्स (नेमस्पेस, ब्लॉक) के साथ बिल्कुल वही व्यवहार है।

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

+0

बाध्यकारी के पीछे अंतर्निहित कारण बताते हुए धन्यवाद; यह वास्तव में कहता है कि मुझे पहली बार यह त्रुटि क्यों मिली और क्यों उपयोग निर्देश ने इसे हल किया। – legends2k

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