2009-10-28 16 views
9

मुझे सी ++ में कुछ परेशानी अधिभार विधियां मिल रही हैं। समस्या का एक उदाहरण के रूप में, मेरे पास एक वर्ग है जिसमें कई विधियों को अधिभारित किया जा रहा है, और प्रत्येक विधि में एक अलग डेटा प्रकार के साथ एक पैरामीटर है। मेरा प्रश्न: क्या क्लास में कोई विशेष क्रम है, यह सुनिश्चित करने के लिए कि सही पैरामीटर को इसके पैरामीटर डेटा प्रकार के आधार पर क्या कहा जाता है?फ़ंक्शन/विधि अधिभार C++: डेटा प्रकार भ्रम?

class SomeClass{ 
    public: 
    ... 
    void Method(bool paramater); 
    void Method(std::string paramater); 
    void Method(uint64_t paramater); 
    void Method(int64_t paramater); 
    void Method(uint8_t paramater); 
    void Method(int8_t paramater); 
    void Method(float paramater); 
    void Method(double paramater); 
    void Method(ClassXYZ paramater); 
} 

मैंने देखा समस्या नहीं थी क्योंकि जब चल रहा है:

Method("string"); 

यह बुला गया था:

Method(bool paramater); 

उत्तर

5

स्ट्रिंग शाब्दिक "string" टाइप const char[] जो implicity bool में बदला जा सकता है। यह आपके अधिभारित कार्यों में से एक के लिए सबसे अच्छा रूपांतरण उम्मीदवार है हालांकि यह सबसे उपयोगी होने की संभावना नहीं है।

आपका इरादा स्ट्रिंग शाब्दिक अधिभार एक std::string लेने के द्वारा नियंत्रित किया जाना है करने के लिए था, तो आप एक अधिभार एक const char* लेने जोड़ सकते हैं और कार्यान्वयन फोन std::string संस्करण बनाने की जरूरत है।

+0

यह पूरी तरह से उत्साहित है। यह संकल्प नियम एक बुनियादी अवधारणा को कम करने में कम पड़ता है। शायद ओपी "घोषणा आदेश द्वारा" अंतर्ज्ञानी दृष्टिकोण बेहतर काम करेगा। –

4

आदेश का कोई महत्व नहीं है। यहां समस्या यह है कि जब आप

Method("string"); 

आप एक कॉन्स char [] पारित कर रहे हैं। यह पूरी तरह से बूल में परिवर्तित हो जाएगा।

Method(std::string("string")); 
+0

कास्ट न करें; निर्माण! std :: स्ट्रिंग ("स्ट्रिंग") (या एक अधिभार कर चार को * की तरह ऊपर कहा) बेशक –

+0

; संपादित, धन्यवाद। – Tomas

23

आदेश कोई फर्क नहीं पड़ता: क्या आप क्या करना चाहते एक std :: स्ट्रिंग स्पष्टतः पास है। कॉल करने का तरीका तर्कों के प्रकारों का विश्लेषण करके और पैरामीटर के प्रकार से मिलान करके चुना जाता है। यदि कोई सटीक मिलान नहीं है, तो सर्वोत्तम मिलान विधि का चयन किया जाता है। आपके मामले में यह bool विधि होता है।

आप const char[7] प्रकार का तर्क दे रहे हैं। सी ++ ओवरलोडिंग नियमों के मुताबिक, सबसे अच्छा तरीका const char[7] क्षय const char * पर जाने और फिर इसे मानक रूपांतरण का उपयोग करके bool में परिवर्तित करना है। std::string में कनवर्ट करने वाला पथ खराब माना जाता है, क्योंकि इसमें const char * से std::string तक उपयोगकर्ता द्वारा परिभाषित रूपांतरण शामिल होगा। आम तौर पर, उपयोगकर्ता द्वारा परिभाषित रूपांतरण मानक रूपांतरणों के लिए ओवरलोड रिज़ॉल्यूशन प्रक्रिया खो देते हैं। यह आपके मामले में भी होता है।

आप std::string संस्करण की आवश्यकता है यहाँ के नाम से जाना, एक स्पष्ट अधिभार const char * प्रकार के लिए std::string प्रकार स्पष्ट रूप से

void Method(const char *paramater /* sic! */) 
{ 
    Method(std::string(paramater)); 
} 
+1

अंडर-डिफ़ाइंड -> उपयोगकर्ता द्वारा परिभाषित? – jalf

+0

फिक्स्ड। धन्यवाद। – AnT

1

के रूप में चार्ल्स पहले ही बताया है, प्रदान करते हैं और तर्क परिवर्तित करके std::string संस्करण के लिए कॉल प्रतिनिधि यह एक अवांछित अंतर्निहित रूपांतरण के कारण होता है। आपको लगता है कि से बचने के लिए चाहते हैं, एक std :: स्ट्रिंग निर्माता का उपयोग करें: Method(std::string("string")); या यह डाली :: स्ट्रिंग एसटीडी:

Method(static_cast<std::string>("string")); 

हालांकि, अपने घोषणाओं के क्रम महत्वपूर्ण नहीं है।इसके अलावा शब्द "पैरामीटर" की अपनी वर्तनी की जाँच;)

1

अलावा स्ट्रिंग मुद्दे से, वहाँ एक और एक है। int64_t और int8_t (आमतौर पर) typedefs हैं। चूंकि टाइपिफ्स केवल उपनाम हैं, इसलिए वे उसी प्रकार का संदर्भ ले सकते हैं जिसमें ओवरलोडिंग काम नहीं करेगी। लेकिन यह आपके मामले में असंभव है। बस इसका जिक्र करना चाहता था।

2

नहीं आपके सवाल का जवाब लेकिन, बस जिज्ञासा से बाहर, वहाँ एक टेम्पलेट विधि का उपयोग कर प्रत्येक प्रकार के लिए एक अधिभार संस्करण को परिभाषित नहीं के बजाय के लिए एक छिपा कारण क्या है?

class SomeClass 
{ 
    public: 
    ... 
    template <typename T> 
    void Method(T paramater); 
}; 
+0

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

1

तुम इतनी के रूप में इरादा तर्क लेने के लिए एक explict कीवर्ड जोड़ सकते हैं।

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