का उद्देश्य सी ++ में एक अपवाद-तटस्थ जेनेरिक स्टैक डेटा संरचना को लागू करना है, केवल टेम्पलेट तर्क डिस्ट्रिक्टर मानते ही नहीं फेंकना। यह चाल संभावित रूप से टेम्पलेट तर्क संचालन (कन्स्ट्रक्टर, कॉपी कन्स्ट्रक्टर, असाइनमेंट) फेंकने के लिए संभाल करने के लिए एक संगत स्थिति में ढेर को छोड़ने के लिए संभालना है।
समाधान में, हर्ब सटर का कहना है
इस समाधान को सरल रखने के लिए, मैंने अपवाद-सुरक्षित संसाधन स्वामित्व के लिए बेस क्लास तकनीक का प्रदर्शन नहीं करने का निर्णय लिया है।
कुछ googling के बाद, मैं डेव द्वारा पाया इब्राहीम 1 99 7 से डेटिंग करते हैं। अपने समाधान में वह बेस क्लास में स्मृति के आवंटन और हटाने का संचालन करता है, और उपवर्ग में स्टैक ऑपरेशन को लागू करता है। इस तरह, वह यह सुनिश्चित करता है कि प्रतिलिपि निर्माता में प्रतिलिपि को कॉपी स्मृति आवंटन से अलग किया जाता है, इसलिए यदि प्रतिलिपि विफल हो जाती है, तो आधार वर्ग नाशक कहा जाता है, कोई बात नहीं।
संदर्भ के लिए, यहां डेव की प्रतिलिपि है मेरी टिप्पणी के साथ कन्स्ट्रक्टर ने कहा:
// v_ स्टैक तत्वों को भंडारित आंतरिक सरणी को संदर्भित करता है स्टैक (कॉन्स्ट स्टैक & amp; rhs): स्टैकबेज & lt; T & gt; (rhsCount ()) // कन्स्ट्रक्टर पर्याप्त स्थान आवंटित करता है / डिस्ट्रक्टर कॉल को [] उचित रूप से हटाना {जबकि (गणना () & lt; rhs.Count ()) पुश (rhs.v_ [गणना ()]);
यदि बेस कन्स्ट्रक्टर सफल होता है, तो बेस डिस्ट्रिक्ट में मेमोरी क्लीन अप की गारंटी होती है, भले ही उप-वर्ग की प्रतिलिपि कन्स्ट्रक्टर फेंकता हो।
मेरे प्रश्न हैं :
- क्या इस दृष्टिकोण के लिए कोई अन्य लाभ है, जैसा कि ऊपर उल्लिखित है?
जब मैं इस समस्या का हल मेरे स्वयं: <पूर्व>
// v_ स्टैक तत्वों को भंडारित आंतरिक सरणी से संदर्भित करता है / बनाम__ v_ // vused_ में आवंटित स्थान की मात्रा है v_ stack में अब तक उपयोग की जाने वाली जगह की मात्रा ( Const स्टैक & amp; rhs): vsize_ (0), vused_ (0), v_ (0) {ढेर temp (rhs.vused_); // कन्स्ट्रक्टर कॉल्स `नई टी [num_elements]` `डिस्ट्रक्टर्स कॉल` को हटाएं [] v_` std :: copy (rhs.v_, rhs.v_ + rhs.vused_, temp.v_); // स्वैप (अस्थायी) फेंक सकता है; } शून्य स्वैप (स्टैक & amp; आरए) {std :: swap (v_, rhs.v_); Std :: swap (vused_, rhs.vused_); Std :: swap (vsize_, rhs.vsize_); }
इस दृष्टिकोण के मुकाबले मुझे बेस क्लास के लिए कुछ मुश्किलें हैं I क्या कोई कारण है कि इस टेम्प्-कॉपी-टू-स्वैप दृष्टिकोण से बेस-क्लास तकनीक को प्राथमिकता दी जानी चाहिए? ध्यान दें कि डेव और मेरे पास पहले से ही
स्वैप () सदस्य है क्योंकि हम इसे अपने
ऑपरेटर = () ।
- डेव इब्राहीम की तकनीक बहुत अच्छी तरह से प्रतीत नहीं होती है (Google के अनुसार)। क्या इसका एक अलग नाम है, क्या यह मानक अभ्यास है, क्या मैंने कुछ याद किया है?
नोट:
- डेव का
पुश () मानें एक लूप में
std :: copy
- के उपयोग के बराबर होने के लिए चलो स्मार्ट पॉइंटर्स को उत्तर से बाहर रख दें, क्योंकि उनका उपयोग स्मृति को प्रबंधित करने की स्थिति को दूर करेगा स्पष्ट रूप से इस अभ्यास में
व्यवहारिक रूप से दो कार्यान्वयन समान हैं। वे दोनों एक प्रबंधित स्मृति आवंटन ऑब्जेक्ट सेटअप करते हैं जो गुंजाइश पर बाहर निकलने पर साफ़ होगा यदि कन्स्ट्रक्टर विफल रहता है। एक अस्थायी चर में कॉपी करना अधिक महंगा हो सकता है, लेकिन जैसा कि टिप्पणियों में लिखा गया है,
std :: move शायद इस तरह की अतिरिक्त लागत को समाप्त कर देगा आपके विशिष्ट प्रश्नों के उत्तर में:
- इब्राहीम का उदाहरण आपके वास्तविक वर्ग के कार्यान्वयन विवरणों से ढेर आबंटन को आगे बढ़ाता है। आपके कोड में, अगर आप अपने सरणी की प्रतिलिपि करने से पहले / बाद में अधिक जटिल मेमोरी हेरफेर करते हैं तो सभी संस्थाओं के सही प्रबंधन को सुनिश्चित करना थोड़ा अधिक कठिन हो सकता है। अन्यथा मुझे पहले विवरण के व्यवहार के संबंध में स्पष्ट रूप से कोई स्पष्ट विवरण दिखाई नहीं देता है।
- इब्राहीम के कार्यान्वयन को एक ही स्थान के लिए साफ़ किया गया है। यदि एकाधिक वर्ग
स्टैकबेज & lt; T & gt; का उपयोग करते हैं, तो वे प्रत्येक को सुरक्षित रूप से अपनी गतिशील मेमोरी मान सकते हैं यदि वे अपवाद फेंक देते हैं अपने कार्यान्वयन में आपको इसे प्राप्त करने के लिए अस्थायी ऑब्जेक्ट और स्वैप कोड को फिर से लिखना होगा (कम से कम भागों) प्रभावी रूप से, यह कार्यान्वयन स्टैकबेज के कई उप-वर्गों को लागू करने के लिए लाइनों की संख्या कम करता है। हालांकि, यदि आप कुछ अन्य बेस क्लास के शीर्ष पर अतिरिक्त मेमोरी आवंटन चाहते हैं, तो आपके कार्यान्वयन में कई विरासत से बचा जाता है। आपका कोड टेम्पलेट कोड ब्लोइंग को समय / आकार संकलित करने से बचा जाता है - हालांकि मैं आम तौर पर इसे अधिकांश मामलों में बड़े नकारात्मक होने पर विचार नहीं करता है। मैं शायद आपके कोड के करीब कुछ को डिफ़ॉल्ट के रूप में इस्तेमाल करूंगा जब तक कि मैं बहुत सामान्य उपयोग केस कोड लिखने की कोशिश नहीं कर रहा था।
- मुझे नहीं पता कि इस दृष्टिकोण का कोई विशिष्ट नाम है - मैं इसे अपडेट करूँगा अगर मुझे एक मिल जाए - लेकिन मैंने इसे कम से कम एक सी ++ प्रोग्रामिंग पुस्तक में पहले देखा है।
No comments:
Post a Comment