2009-12-13 17 views
53

मैंने अपनी समस्या को समझाने के लिए नीचे दिया गया कोड लिखा था। अगर मैं लाइन 11 पर टिप्पणी करता हूं (कीवर्ड "उपयोग" के साथ), संकलक फ़ाइल को संकलित नहीं करता है और यह त्रुटि प्रदर्शित करता है: invalid conversion from 'char' to 'const char*'। ऐसा लगता है कि कक्षा में Parent कक्षा के void action(char) विधि को नहीं देखा गया है।मुझे अपनी बेस क्लास विधि तक पहुंचने के लिए "उपयोग" कीवर्ड का उपयोग क्यों करना चाहिए?

संकलक इस तरह से व्यवहार क्यों करते हैं? या मैंने कुछ गलत किया है?

class Parent 
{ 
    public: 
     virtual void action(const char how){ this->action(&how); } 
     virtual void action(const char * how) = 0; 
}; 

class Son : public Parent 
{ 
    public: 
     using Parent::action; // Why should i write this line? 
     void action(const char * how){ printf("Action: %c\n", *how); } 
}; 

int main(int argc, char** argv) 
{ 
    Son s = Son(); 
    s.action('a'); 
    return 0; 
} 
+0

कृपया मुझे बताएं: क्या होगा यदि आप "कॉन्स्ट चार कैसे" में कॉन्स्ट को हटा दें? –

+24

आपको 'सोन एस = सोन();' टाइप करने की आवश्यकता नहीं है। यह सिर्फ अस्थायी बनाता है और फिर कॉपी कन्स्ट्रक्टर को कॉल करता है। बस 'सोन एस;' –

+3

टाइप करें हमें यह प्रश्न बहुत कम मिलता है: [http://stackoverflow.com/questions/1835988 ](httpoverflow.com/questions/1835988) [http://stackoverflow.com/ प्रश्न/411103] (http://stackoverflow.com/questions/411103) [http://stackoverflow.com/questions/1480085 ](httpoverflow.com/questions/1480085) [http: // stackoverflow। कॉम/प्रश्न/17 99 4 9 7] (http://stackoverflow.com/questions/1799497) [http://stackoverflow.com/questions/888235 ](httpoverflow.com/questions/888235) [http: // stackoverflow.com/questions/72010 ](httpoverflow.com/questions/72010) –

उत्तर

47

action व्युत्पन्न वर्ग में घोषित देखें छुपाता action आधार वर्ग में घोषित कर दिया। यदि आप ऑब्जेक्ट पर action का उपयोग करते हैं तो संकलक Son में घोषित विधियों में खोज करेगा, जिसे action कहा जाता है, और इसका उपयोग करें। यह बेस क्लास के तरीकों में खोज नहीं करेगा, क्योंकि इसे पहले से ही एक मिलान नाम मिला है।

तब वह विधि कॉल के पैरामीटर से मेल नहीं खाती है और आपको कोई त्रुटि मिलती है।

इस विषय पर अधिक स्पष्टीकरण के लिए C++ FAQ भी देखें।

+8

@sth यह जानना अच्छा है। लेकिन क्या यह मैं कह सकता हूं, सी ++ या किसी प्रकार की बग की सुविधा? क्या यह विरासत के पूरे विचार को खराब नहीं करता है? बस पूछना .. – Anubis

+0

क्या नाम का नाम बदलकर नाम मिलान किया गया है, क्या विधि ओवरलोडिंग यहां एक भूमिका निभाती है, या पहला फ़ंक्शन है जिसका नाम "एक्शन" है और यह है? – tmaric

+3

@Anubis: नियम नाम लुकअप को सरल बनाता है। इसके बिना, कंपाइलर को पूर्ण विरासत पेड़ पर चलने की आवश्यकता होगी जब इसे किसी सदस्य फ़ंक्शन के नाम को हल करने की आवश्यकता होती है (कुछ बेस क्लास में फ़ंक्शन का ओवरलोड हो सकता है)।नियम के साथ, संकलक एक फिटिंग नाम वाले वर्ग को मिलने के बाद शेष विरासत के पेड़ को देख सकता है। प्रोग्रामर एक ही स्थिति में है। व्युत्पन्न वर्ग को देखते हुए वह यह सुनिश्चित कर सकता है कि वहां परिभाषित कार्य को बिना किसी नाम के बताए रखा जा सकता है कि कुछ बेस क्लास में एक ही नाम का एक अलग कार्य हो सकता है। – sth

15

आश्चर्य की बात यह मानक व्यवहार है। यदि व्युत्पन्न वर्ग बेस क्लास द्वारा परिभाषित विधि के समान नाम के साथ एक विधि घोषित करता है, तो व्युत्पन्न वर्ग 'विधि बेस क्लास को छुपाती है' एक।

C++ FAQ

5

सावधानी का एक नोट: इस स्थिति में "उपयोग" का उपयोग करने की आवश्यकता एक लाल झंडा है कि आपका कोड अन्य डेवलपर्स के लिए भ्रमित हो सकता है (इसके बाद यह संकलक उलझन में है!)। यह संभावना है कि आपको अन्य प्रोग्रामर को भेद स्पष्ट करने के लिए दो विधियों में से एक का नाम बदलना चाहिए।

एक संभावना:

void action(const char how) 
{ 
    takeAction(&how); 
} 
void action(const char * how) 
{ 
    takeAction(how); 
} 
virtual void takeAction(const char * how) = 0; 
3

एक व्युत्पन्न वर्ग किसी भी अधिक लोड समारोह में नए सिरे से परिभाषित किया जाता है तो आधार वर्ग में सभी अतिभारित समारोह छिपा हुआ है। दोनों कार्यक्षमताओं को शामिल करने का एक तरीका कक्षाओं में कार्य ओवरलोडिंग से बचने के लिए है। या आप उपयोग किए गए using कीवर्ड का उपयोग कर सकते हैं।

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