2011-08-24 10 views
6

पृष्ठभूमि: मैं कई चर के साथ एक जटिल वर्ग की है।क्या मैं ऑपरेटर = में प्लेसमेंट नया (यह) उपयोग कर सकता हूं?

Applepie::Applepie(const Applepie &copy) : 
m_crust(copy.m_crust), 
m_filling(copy.m_filling) 
{ 
} 

सदस्य चर प्रति कंस्ट्रक्टर्स intializer सूची में कहा जाता है में से कुछ आवंटन करते हैं: मैं एक ध्वनि और परीक्षण प्रतिलिपि निर्माता है।

प्रश्न: मुझे operator= बनाने की आवश्यकता है। बल्कि काम के बजाय प्रारंभ सूची, और मुक्त कराने स्मृति मौजूदा constuctor कि प्रतिस्थापित किया जा रहा है डुप्लिकेट, और आदि आदि आदि, मैं बस निम्न कर सकते हैं की तुलना में:

Applepie& Applepie::operator=(const Applepie &copy) 
{ 
    if(this != &copy) 
    { 
     this->~Applepie(); // release own object 
     new(this) Applepie(copy); // placement new copy constructor 
    } 
    return *this; 
} 

दूसरे शब्दों में, एक प्लेसमेंट के बाद स्वयं को नष्ट है नई प्रतिलिपि कन्स्ट्रक्टर semantically ऑपरेटर के समान =?

इस क्षमता में नाटकीय रूप से बार-बार कोड और पुष्टि है कि प्रत्येक चर ठीक से प्रारंभ होता है, काम के दौरान दक्षता के संभावित मामूली नुकसान की कीमत पर कम करने के लिए लगता है। क्या मुझे कुछ और अस्पष्ट याद आ रही है?

तर्क: मेरी वास्तविक कक्षा में लगभग 30 varaibles हैं। मैं इस तथ्य से चिंतित हूं कि मेरी प्रतिलिपि निर्माता और मेरे असाइनमेंट ऑपरेटर दोनों को तीस तीस की प्रतिलिपि बनाना है, और कोड अलग हो सकता है, जिससे दोनों परिचालन अलग-अलग काम कर सकते हैं।

+4

प्रतिलिपि ctor फेंकता है, तो आप वस्तु हड्डी टूट गई है, तो आप किसी भी expection सुरक्षा की गारंटी देता है दे रही है नहीं कर रहे हैं। –

+1

@ आर मार्टिनो - मुझे ऐसा लगता है कि कॉपी सीटीर फेंकने वाली किसी भी स्थिति से मेरा ऑपरेटर = फेंकने का कारण बनता है अगर मैं प्रत्येक चर को मैन्युअल रूप से असाइन कर रहा था ... तो ... यह अभी भी बराबर लगता है? – jcwenger

+3

समस्या 'ऑपरेटर =' फेंकना नहीं है, 'ऑपरेटर =' ऑब्जेक्ट को अमान्य स्थिति में छोड़ रहा है! यह नष्ट हो गया है। –

उत्तर

6
"असाधारण सी ++" राज्यों में

हर्ब Sutter रूप में, यह अपवाद सुरक्षित नहीं है। इसका मतलब है कि अगर कुछ भी new या नई वस्तु के निर्माण के दौरान गलत हो रहा है, काम के बाएं हाथ संकार्य बुरा (अपरिभाषित) राज्य में है, और अधिक परेशानी के लिए बुला। मैं copy & swap idiom का उपयोग करने की दृढ़ता से अनुशंसा करता हूं।

Applepie& Applepie::operator=(Applepie copy) 
{ 
    swap(m_crust, copy.m_crust); 
    swap(m_filling, copy.m_filling); 
    return *this; 
} 

अपने वस्तु Pimpl मुहावरा (कार्यान्वयन के लिए सूचक) का उपयोग करता है भी, स्वैप केवल दो संकेत बदलने के द्वारा किया जाता है।

+1

+1 'स्वैप' एक अद्भुत अविकसित है फ़ंक्शन ... अतिरिक्त लाभ: यदि तर्क एक रावल्यू है तो संकलक कॉपी एलिशन कर सकता है। –

+0

तो ... इसके साथ मेरा मुद्दा यह है कि मेरी वास्तविक कक्षा में लगभग 30 चर हैं। मेरी प्रतिलिपि निर्माता में प्रारंभकर्ता सूची में सभी 30 चर हैं। कॉपी और स्वैप अभी भी मुझे 30 स्वैप() कॉल करने की आवश्यकता होगी - मेरी ऑब्जेक्ट ऐप्पल पाई (मूल) की संभावना को कम करने के लिए है; और ऐप्पल सेब; सेब = मूल; विभिन्न परिणाम उत्पन्न करें। – jcwenger

+0

@jcwenger: हाँ, यह मुसीबत का आह्वान है। तो यह * Pimpl * idiom के लिए एक उम्मीदवार हो सकता है, लेकिन उस पर स्विच करने से पहले, मान लें कि यह एक लागत पर आ रहा है: प्रत्येक सदस्य का उपयोग तब एक सूचक के माध्यम से जा रहा है। एक और विचार आपके 'ऐप्पलपी' वर्ग को छोटे टुकड़ों में विभाजित करना होगा। यदि आपके पास एक कक्षा में 30 डेटा सदस्य हैं, तो डिज़ाइन के साथ कुछ गलत हो सकता है ... –

0

रीन के उत्तर के अलावा, क्या होगा यदि ऐप्पलपी वास्तविक वस्तु का आधार वर्ग था: ApplePie ऑब्जेक्ट को गलत प्रकार की वस्तु के साथ बदल देगा!

+1

ऑपरेटर = ऑब्जेक्ट स्लाइसिंग * वैसे भी करेगा, अगर ऑब्जेक्ट को हैंडल-वर्कर मुहावरे में लागू नहीं किया गया है। –

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

  • कोई संबंधित समस्या नहीं^_^