2012-01-14 24 views
5

मेरे पास Location नामक एक कक्षा है और मुझे इसके सदस्य चरों में एक कैरे जोड़ने की आवश्यकता है। इस परिवर्तन ने असाइनमेंट ऑपरेटर को अधिभारित करने की आवश्यकता को जन्म दिया।सी ++ ओवरलोडिंग असाइनमेंट ऑपरेटर

क्या इस वर्ग प्रकार में सभी चरों की प्रतिलिपि बनाने का कोई तरीका है जिसे मैंने बदलाव करने से पहले कॉपी किया जा रहा था और केवल प्रत्येक सदस्य चर को व्यक्तिगत रूप से कॉपी किए बिना कैरे की प्रतिलिपि बनाने के लिए अतिरिक्त कोड जोड़ दिया है?

Location& Location::operator=(const Location &rhs) 
{ 
    // Only do assignment if RHS is a different object from this. 
    if (this != &rhs) 
    { 
     //Copy CArray 
     m_LocationsToSkip.Copy(rhs.m_LocationsToSkip); 

     //Copy rest of member variables 
     //I'd prefer not to do the following 
     var1 = rhs.var1; 
     var2 = rhs.var2; 
     //etc 
    } 

    return *this; 
} 
+0

तो तुम करने के लिए, प्रभाव में, संकलक उत्पन्न असाइनमेंट ऑपरेटर कॉल करना चाहते हैं? क्या 'कैरे' के पास असाइनमेंट ऑपरेटर है? –

+0

इसमें एक कॉपी कन्स्ट्रक्टर है लेकिन कोई असाइनमेंट ऑपरेटर नहीं है। मुझे यकीन नहीं है कि मैं संकलक जेनरेट असाइनमेंट ऑपरेटर को कॉल कर सकता हूं क्योंकि मैंने एक कैरे सदस्य चर जोड़ा है। –

+2

नहीं, आप संकलक को जेनरेट नहीं कर सकते हैं क्योंकि जब आप एक प्रदान करते हैं तो यह उत्पन्न नहीं होता है (नहीं क्योंकि आपने एक कैरे सदस्य जोड़ा है; केवल एक चीज जो बदलती है वह है कि आपकी कक्षा के लिए जेनरेट किया गया कंपाइलर कॉल नहीं कर सकता एक कैरे के लिए क्योंकि यह अस्तित्व में नहीं है)। मुझे डर है कि ऐसा करने का कोई तरीका नहीं है। –

उत्तर

4

हां, तरह। एक प्रकार का उपयोग करें जो operator= को अधिभारित करता है, इसलिए आपको इसके बजाय युक्त कक्षा में ऐसा करने की आवश्यकता नहीं है। एमएफसी कोड लिखते समय भी, मैं अब भी एमएफसी संग्रह और स्ट्रिंग कक्षाओं के बजाय std::vector, std::string इत्यादि का उपयोग करता हूं। कभी-कभी आप CString का उपयोग करके बहुत अधिक अटक जाते हैं, लेकिन मुझे पिछली बार याद नहीं आया कि मैंने std::vector के बजाय CArray का उपयोग किया था।

+0

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

0

नहीं आप नहीं कर सकते। ऐसा करने का सबसे अच्छा तरीका वास्तविक कोड उत्पन्न करने के लिए स्क्रिप्ट का उपयोग करना है।

0

आमतौर पर इसे "कॉपी और स्वैप मुहावरे" कहा जाता है। आप एक कॉपी कन्स्ट्रक्टर और swap() विधि लागू करते हैं जो सदस्य मानों का आदान-प्रदान करता है और, सबसे महत्वपूर्ण बात यह है कि बाह्य डेटा के पॉइंटर्स।

C& C::operator=(const C& c) { 
    C tmp(c); 
    this->swap(tmp); 
    return *this; 
} 

तुम भी इस के साथ एक स्वयं काम गार्ड की जरूरत नहीं है: कि अपने असाइनमेंट ऑपरेटर की तरह लग रहा है।

+0

लेकिन अब आपको अपने 'स्वैप' कार्यान्वयन में सभी सदस्यों को गिनना होगा। यह सिर्फ समस्या को हल करता है, यह इसे हल नहीं करता है। –

+0

ठीक है, मुझे यहां कोई समस्या नहीं दिखाई दे रही है। बहुत सारे मूल्य सदस्य? उन्हें एक स्ट्रक्चर में पैकेज करें और यदि आप कम टाइपिंग के लिए जा रहे हैं तो बस एक असाइनमेंट करें। –

2

हां। मैं आमतौर पर जो कुछ भी कॉपी नहीं करता, उसे छोड़कर वर्ग में सदस्यों की संरचना में सबकुछ रखना है। इस तरह:

class Location 
{ 
    struct Members 
    { 
     int var1, var2; 
    }; 

    Members m; 
    CArray m_LocationsToSkip; 

public: 
    Location& operator=(Location const& rhs); 
}; 

Location& Location::operator=(const Location &rhs) 
{ 
    // Only do assignment if RHS is a different object from this. 
    if (this != &rhs) 
    { 
     //Copy CArray 
     m_LocationsToSkip.Copy(rhs.m_LocationsToSkip); 

     //Copy rest of member variables 
     m = rhs.m; //will use Members automatically generated operator= 
        //which should do the correct thing because you only put 
        //normally copyable members in m 
    } 

    return *this; 
} 

मैं पहली बार इस बारे में यहाँ पोस्ट: https://stackoverflow.com/questions/469696/what-is-your-most-useful-c-c-utility/1609496#1609496

+0

यह एक सभ्य समाधान की तरह लगता है लेकिन इसका समर्थन करने के लिए शेष एप्लिकेशन में यह काफी हद तक रिफैक्टरिंग लेगा। –

+0

@ कोले डब्ल्यू: कैसे? आपके सदस्य सार्वजनिक हैं और एप्लिकेशन में हर जगह इस्तेमाल किए जाते हैं? उस स्थिति में, एक और विकल्प एक संसाधन-प्रबंधन वर्ग बनाना होगा जो कैरेरे को एंग्लोब (कुछ हद तक उदाहरण के मुकाबले दूसरी तरफ) करने के लिए होगा, इसलिए आपके पास संभवतः केवल एक सदस्य होगा जिसके लिए रिफैक्टरिंग की आवश्यकता हो सकती है (संभवतः इसका उपयोग कैसे किया जाता है इसके आधार पर नहीं)। मैंने उस उदाहरण को स्ट्रक्चर के साथ इस्तेमाल किया क्योंकि मुझे अपने कोड में यही चाहिए (यह सूचक के लिए था, एक सरणी नहीं, और एक स्मार्ट पॉइंटर जो मुझे चाहिए था) लेकिन आपके मामले में, कैरे के लिए संसाधन-प्रबंधन वर्ग बनाना बेहतर विकल्प बनें। – n1ckp

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