2012-01-30 12 views
15

मैं अपने सी ++ में कुछ संशोधन कर रहा हूं, और मैं मिनट में ऑपरेटर ओवरलोडिंग से निपट रहा हूं, खासकर "=" (असाइनमेंट) ऑपरेटर। मैं ऑनलाइन देख रहा था और चर्चा करने वाले कई विषयों पर आया। मेरे अपने नोट्स में, मैं अपने सभी उदाहरणों की तरहअसाइनमेंट ऑपरेटर ऑब्जेक्ट का संदर्भ क्यों देता है?

class Foo 
{ 
    public: 
     int x; 
     int y; 
     void operator=(const Foo&); 
}; 
void Foo::operator=(const Foo &rhs) 
{ 
    x = rhs.x; 
    y = rhs.y; 
} 

कुछ के रूप में नीचे ले जाया सभी संदर्भों को मैं ऑनलाइन पाया है, मैंने देखा है कि ऑपरेटर स्रोत ऑब्जेक्ट के लिए एक संदर्भ देता है। ऑब्जेक्ट के संदर्भ को वापस करने का सही तरीका क्यों नहीं है जैसा कि कुछ भी नहीं है?

+0

सही तरीका है जो कुछ भी तरह से अर्थ विज्ञान आप चाहते हैं को लागू करता है; _idiomatic_ तरीका निश्चित रूप से 'टी &' ('आपके उदाहरण में' Foo & ') वापस करने के लिए है। – ildjarn

+0

@MooingDuck, मुझे लगता है कि मैंने गलत सवाल का जवाब दिया। मैं इस धारणा पर जा रहा था कि मेरे नोट गलत थे, लेकिन जानना चाहते थे कि क्यों अधिक से अधिक सही था। की – maccard

+1

संभव डुप्लिकेट [असाइनमेंट ऑपरेटर एक संदर्भ वापस जाने के लिए * यह C++] (http://stackoverflow.com/questions/5669813/assignment-operator-return-a-reference-to-this-in-c); भी [एक असाइनमेंट ऑपरेटर के साथ इस * रिटर्निंग] (http://stackoverflow.com/questions/3248469/returning-this-with-an-assignment-operator) –

उत्तर

17

सामान्य रूप लक्ष्य वस्तु के लिए एक संदर्भ रिटर्न काम श्रृंखलन अनुमति देने के लिए। अन्यथा, यह करने के लिए संभव नहीं होगा:

Foo a, b, c; 
// ... 
a = b = c; 

फिर भी, यह ध्यान रखें कि सही असाइनमेंट ऑपरेटर is tougher than it might seem रही।

+0

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

13

वापसी प्रकार जब आप सिर्फ इस तरह एक बयान में एक भी काम प्रदर्शन कर रहे हैं कोई फर्क नहीं पड़ता:

if ((x = y)) { 

:

x = y; 

यह जब आप ऐसा करते हैं बात शुरू होता है। .. और वास्तव में मायने रखती है जब आप ऐसा करते हैं:

x = y = z; 

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

+0

मुझे समझ में नहीं आता कि आप क्यों कहते हैं "इससे कोई फर्क नहीं पड़ता"। या तो यह मायने रखता है या यह नहीं करता है। क्या आप विस्तार से बता सकते हैं? – balajeerc

+3

@balajeerc: "यह मामला शुरू होता है" अंग्रेजी में इसका अर्थ है "यह बाद की स्थिति में महत्वपूर्ण है लेकिन पूर्व नहीं।" दूसरे शब्दों में, "जब स्थिति ए से बी में बदलते हैं, तो महत्व ('पदार्थ') शून्य से nonzero तक जाता है"। सीधे असाइनमेंट में वापसी कोई फर्क नहीं पड़ता। एक सशर्त के अंदर यह महत्वपूर्ण है कि यदि आप जो चीज लौटते हैं वह सच या गलत है, लेकिन यह बिल्कुल सही नहीं है। जंजीर असाइनमेंट मामले में, आप वास्तव में वापसी को वर्तमान ऑब्जेक्ट चाहते हैं क्योंकि परिणाम अन्यथा विपरीत होंगे। – Borealid

8

आपका असाइनमेंट ऑपरेटर हमेशा इन तीन बातें करना चाहिए:

  1. असाइनमेंट के दाहिने हाथ की ओर के रूप में एक स्थिरांक-संदर्भ इनपुट (const MyClass &rhs) लो। इसका कारण स्पष्ट होना चाहिए, क्योंकि हम उस मूल्य को गलती से बदलना नहीं चाहते हैं; हम केवल बाएं हाथ की ओर क्या बदलना चाहते हैं।

  2. हमेशा की तरह, return *this नव बदल बाएं हाथ की ओर के लिए एक संदर्भ लौट आते हैं। यह ऑपरेटर चेनिंग की अनुमति देने के लिए है, उदा। a = b = c;

  3. हमेशा स्वयं काम (this == &rhs) लिए जाँच करें। यह विशेष रूप से महत्वपूर्ण है जब आपकी कक्षा अपनी याददाश्त आवंटन करती है।

    MyClass& MyClass::operator=(const MyClass &rhs) { 
        // Check for self-assignment! 
        if (this == &rhs) // Same object? 
         return *this; // Yes, so skip assignment, and just return *this. 
    
        ... // Deallocate, allocate new space, copy values, etc... 
    
        return *this; //Return self 
    } 
    
+1

स्व-असाइनमेंट की जांच करना एक बेवकूफ समाधान है, सही एक कॉपी-एंड-स्वैप है। –

+0

प्रतिक्रिया के लिए धन्यवाद, लेकिन मैं केवल स्वयं असाइनमेंट चेक छोड़कर एक साधारण उदाहरण बनाने की कोशिश कर रहा था। मैं सब कुछ समझने के लिए सब कुछ समझ गया। – maccard

+0

@MatteoItalia कॉपी-एंड-स्वैप महंगा हो सकता है। उदाहरण के लिए, कॉपी-एंड-स्वैप का उपयोग होने पर, एक बड़े वेक्टर को दूसरे के लिए असाइनमेंट लक्ष्य की स्मृति का पुन: उपयोग नहीं कर सकता है। –

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

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