के लिए एक आधार वर्ग तकनीक GotW#8 का कार्य C++ में एक अपवाद के तटस्थ सामान्य ढेर डेटा संरचना को लागू करने, यह मानते हुए केवल टेम्पलेट तर्क नाशक फेंक नहीं करता है। यह चाल संभावित रूप से टेम्पलेट तर्क संचालन (कन्स्ट्रक्टर, कॉपी कन्स्ट्रक्टर, असाइनमेंट) को फेंकने के लिए एक स्थिर स्थिति में स्टैक छोड़ने के तरीके को संभावित रूप से फेंकने के लिए है।अपवाद हैंडलिंग
समाधान में, हर्ब Sutter
इस समाधान सरल रखने के लिए कहते हैं, मैं अपवाद-सुरक्षित संसाधन स्वामित्व के लिए आधार वर्ग तकनीक का प्रदर्शन नहीं करने का फैसला किया है।
कुछ Googling के बाद, मैं द्वारा डेव इब्राहीम 1997 से किए गए उनके समाधान में उन्होंने आवंटन और आधार वर्ग में स्मृति का विलोपन संभालती है, और उपवर्ग में ढेर संचालन लागू करता this answer पाया। इस तरह, वह प्रतिलिपि निर्माता में उस तत्व नकल, स्मृति आवंटन से अलग किया जाता है ताकि यदि नकल विफल रहता है, आधार वर्ग नाशक, कहा जाता है कोई बात नहीं क्या करता है।
संदर्भ के लिए, मेरी टिप्पणी के साथ डेव प्रतिलिपि निर्माता जोड़ा है:
// v_ refers to the internal array storing the stack elements
Stack(const Stack& rhs)
: StackBase<T>(rhs.Count()) // constructor allocates enough space
// destructor calls delete[] appropriately
{
while (Count() < rhs.Count())
Push(rhs.v_[ Count() ]); // may throw
}
आधार निर्माता सफल होती है, आधार नाशक में स्मृति सफाई की गारंटी है, भले ही उपवर्ग के प्रति निर्माता फेंकता है।
मेरे प्रश्न हैं:
- वहाँ दृष्टिकोण के लिए किसी भी अन्य लाभ है, जैसा कि ऊपर उल्लिखित को छोड़कर?
मैं जब मैं अपने दम पर समस्या हल इस प्रति-निर्माता के साथ आया था:
// v_ refers to the internal array storing the stack elements // vsize_ is the amount of space allocated in v_ // vused_ is the amount of space used so far in v_ Stack (const Stack &rhs) : vsize_ (0), vused_ (0), v_ (0) { Stack temp (rhs.vused_); // constructor calls `new T[num_elements]` // destructor calls `delete[] v_` std::copy (rhs.v_, rhs.v_ + rhs.vused_, temp.v_); // may throw swap (temp); } void swap (Stack &rhs) { std::swap (v_, rhs.v_); std::swap (vused_, rhs.vused_); std::swap (vsize_, rhs.vsize_); }
मैं इसे कुछ बोझिल एक आधार वर्ग के लिए जब इस दृष्टिकोण की तुलना में पाते हैं। क्या इस टेम्प-कॉपी-फिर-स्वैप दृष्टिकोण पर बेस-क्लास तकनीक को प्राथमिकता दी जानी चाहिए? ध्यान दें कि दोनों डेव और मैं पहले से ही
swap()
सदस्य है क्योंकि हम अपनेoperator=()
में इसका इस्तेमाल करते हैं।- डेव इब्राहीम 'तकनीक बहुत अच्छी तरह से (गूगल के अनुसार) नाम से जाना प्रतीत नहीं होता। क्या इसका कोई अलग नाम है, क्या यह मानक अभ्यास है, क्या मुझे कुछ याद आया है?
नोट्स:
- मान डेव
Push()
एक पाश मेंstd::copy
- की मेरी उपयोग के बराबर होने का के स्मार्ट संकेत दिए गए जवाब से बाहर रखने, के रूप में उनके उपयोग दूर के प्रबंधन की बात ले जाएगा जाने इस अभ्यास में स्पष्ट रूप से स्मृति
आधार साझा करना आधार वर्ग दृष्टिकोण के पक्ष में एकमात्र तर्क प्रतीत होता है। मैं इसे देखने के लिए एक या दो दिन दूंगा कि कोई और तर्क के साथ आता है या नहीं। – Irfy
बेस वर्ग दृष्टिकोण जीतता है जब ऑब्जेक्ट की सामग्री भारी हैं और 'temp' साथ अदला-बदली महंगा है। (हालांकि सी ++ 11 की 'चाल' मदद कर सकती है) यदि आप चाहें तो आप इसे अपने उत्तर में जोड़ सकते हैं। – Irfy