2014-10-30 6 views
7

पर लागू किए गए सी ++ में 'उपयोग' कीवर्ड के डाउनसाइड्स मैंने हाल ही में using कीवर्ड का एक नया एप्लिकेशन खोजा है; namespace कार्यक्षमता के संदर्भ में नहीं बल्कि एक व्युत्पन्न कक्षा घोषणा के अंदर। मेरे मामले में यह 'ऑपरेटर =' सदस्य-फ़ंक्शन के आस-पास के मुद्दों के संबंध में प्रासंगिक था।व्युत्पन्न कक्षाओं

मैं एक स्थिति है जहाँ, घोषणाओं दिया था:

class CString{ 
public: 
    ...//Various functions. 
    operator=(const CString &cString) 
    { 
     //code to share internal array and increment reference count 
    } 
    operator=(const wchar_t *pstrString) 
    { 
     //code to create a personal internal array, 
     //resize it appropriately and copy the pstrString argument. 
    } 
    ... 
}; 

class CStringEx : public CString{ 
    ...//various members that expand upon CString's abilities. 
}; 

... CStringEx की एक वस्तु के रूप में मैं उम्मीद काम नहीं किया:

CStringEx cString; 

cString=L"String contents"; 

बजाय एक संकलक त्रुटि जनरेट किया गया था बताते हुए ' CStringEx में कोई 'ऑपरेटर =()' फ़ंक्शन नहीं है जो wchar_t * '(या - बहुत करीब - उस प्रभाव के लिए शब्द) का तर्क लेता है। काफी अध्ययन के बाद मैंने यह सीखा है क्योंकि स्वचालित रूप से संकलक-उत्पन्न operator= व्युत्पन्न वर्ग के सदस्य-कार्य भी अपने मूल वर्ग से विरासत में प्राप्त हुए हैं। यह काउंटर-अंतर्ज्ञानी और उपयोगकर्ता- संयुक्त राष्ट्र मेरे अनुकूल है।

हालांकि

, अगर मैं एक using कीवर्ड जोड़ने:

class CStringEx : public CString{ 
public: 
    using CString::operator=; 
    ... 
}; 

... बच्चे वर्ग अब अपने माता-पिता की operator= सदस्य समारोह और सभी का उपयोग करेगा अच्छी तरह से है।

अभी तक, बहुत अच्छा है। हालांकि, यहां और कहीं और पढ़ने के बाद मैंने सीखा है कि कई प्रोग्रामर इस उद्देश्य के लिए using का उपयोग करना पसंद नहीं करते हैं। उदाहरण के लिए मैंने कुछ टिप्पणीकारों को पढ़ा है जो संभावित रूप से अवांछित साइड इफेक्ट्स का वर्णन करते हैं, जैसे माता-पिता से सभी ऑपरेटर = में ब्रिनिंग। हालांकि, फिर, बहुत विशिष्ट परिस्थितियों के अलावा मुझे समझ में नहीं आता कि सभी मूल सदस्य-कार्यों को विरासत में क्यों लेना और मुद्दा होना चाहिए। यदि यह कोई बड़ी चिंता है तो क्या कोई ऐसा करने के सामान्य खतरों को समझा सकता है?

class CStringEx : public CString{ 
public: 
    ... 
    const CStringEx& operator=(const wchar_t* pstrString) 
    { 
     CString::operator=(pstrString); 
     return *this; 
    } 
    const CStringEx& operator=(const CString &cString) 
    { 
     CString::operator=(cString); 
     return *this; 
    } 
    ...//and so on... 
}; 

जब:

एकमात्र विकल्प मैं के बारे में सोच सकते हैं के लिए बच्चे को कक्षा में ठूंठ कार्यों को लिखने के लिए हरoperator= इसके बारे में सदस्य-समारोह माता पिता है और फिर स्पष्ट रूप से उन संबंधित सदस्य-कार्यों कहते हैं using CString::operator= के साथ संस्करण की तुलना में यह मेरे लिए बेहद बदसूरत, बोझिल और गन्दा दिखता है। तो फिर, using कीवर्ड का उपयोग क्यों न करें?

तो using इस काम के लिए सही उपकरण है, तो आप इसका इस्तेमाल करना चाहिए:

+5

"मैंने सीखा है कि कई प्रोग्रामर इस उद्देश्य के लिए उपयोग करना पसंद नहीं करते हैं।" बकवास। यदि यह सही उपकरण है, तो यह सही टूल है। –

+0

"मुझे समझ में नहीं आता क्यों। क्या कोई ऐसा करने के खतरों को समझा सकता है?" संभवतया आपने जो भी तर्क अपने प्रश्न से छोड़ा है, वह इस बात का संकेत दे सकता है। –

+0

वाह ... यह थोड़ा एस्सेबिक remyable है! लेकिन ठीक है; आप का मतलब है उन लोगों का तर्क जो __using__ का उपयोग करना पसंद नहीं करते? यदि ऐसा है, तो उदाहरण के लिए [लिंक] http://stackoverflow.com/questions/4122214/why-operator-doesnt-get-inherited-from-a-template-class [/ link] और _David Rodríguez_ टिप्पणियां। स्पष्टीकरण देना; मुझे समझ में नहीं आता कि वह जिस स्थिति का वर्णन करता है वह 'खराब' होगा और इसके बजाए स्टब-फ़ंक्शन दृष्टिकोण का उपयोग करने का एक कारण होगा। उस पोस्ट और दूसरों में _using_ के लिए समान निराशा के अन्य उदाहरण हैं। –

उत्तर

1

यह तो चलो की समीक्षा हम क्या पता है एक सा व्यक्तिपरक है। यही कारण है कि ने कहा:

  • usingहमेशासभी माता पिता के तरीकों/ऑपरेटरों, यहां तक ​​कि नए जोड़े गए जो कि आप इरादा कभी नहीं में लाएगा। यह तब भी टूटा हुआ कोड हो सकता है जब कोई अभिभावक असाइनमेंट ऑपरेटर बनाता है जो बच्चे के ऑब्जेक्ट के साथ अच्छी तरह से बातचीत नहीं करता है।
  • अभिभावक की कॉपी असाइनमेंट ऑपरेटर में लाने का अर्थ है कि आप CString से बना सकते हैं लेकिन शायद यह इरादा व्यवहार है।
  • भविष्य पाठकों/रखरखाव सिंटैक्स का उपयोग कर ऑपरेटर से परिचित नहीं हो सकते हैं और कोड को गड़बड़ करने के लिए थोड़ा कठिन बना सकते हैं।

इस तथ्य को देखते हुए कि आप मूल रूप से पूछ रहे हैं (आपके द्वारा सुनाई गई चीज़ों के आधार पर) और ऊपर दिए गए अंक, चलिए वापस कदम उठाएं और एक पल को अपने पल को देखें। CStringEx में दो संभावनाएं हैं:

  1. इसमें अतिरिक्त डेटा सदस्य हैं। इस मामले में मैं यह कहने के लिए तैयार हूं कि विरासत माता-पिता ऑपरेटर कुछ या सभी मामलों में कुछ गलत करने जा रहे हैं, क्योंकि बाल वर्ग के सदस्यों को असाइनमेंट में संभाला नहीं जाएगा।
  2. इसमें अतिरिक्त डेटा सदस्य नहीं हैं, यह केवल अतिरिक्त कोड कार्यक्षमता प्रदान करता है। इस मामले में, कृपया बच्चे वर्ग का उपयोग करने के लिए परीक्षा न लें। इसके बजाय फ्री-फ़ंक्शन एल्गोरिदम लिखें जो या तो (इटरेटर) श्रेणियों पर काम करते हैं या यदि आपको CString ऑब्जेक्ट्स चाहिए।
+0

** बहुत **, बहुत अच्छी तरह से मार्क डालें !!! मैं बाल वर्ग की बजाय बाहरी कार्यों का उपयोग करने के विचार से थोड़ा असहज हूं - लेकिन मुझे लगता है कि मैं उन खतरों को समझता हूं जिन्हें आप रेखांकित करते हैं। आप जो वर्णन करते हैं वह बहुत ही समान लगता है कि हेवलेट पैकार्ड एसटीएल फ़ंक्शन बाहरी एल्गोरिदम के साथ कैसे काम करता है और आगे यह है कि 'क्लिप ऑन' और कई ऑब्जेक्ट प्रकारों के साथ जाल करें। अभी तक मैंने इन नए विचारों से सीखा या परिचित नहीं किया है - लेकिन भविष्य में यह निश्चित रूप से कुछ देखना है। मैंने फिर भी एक इटरेटर लिखा है, इसलिए स्ट्रिंग नए 'के लिए (:) 'रेंज लूप के साथ काम करेगी। –

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