2012-10-04 19 views
6

संभव डुप्लिकेट:
How to clean initialized resources if exception thrown from constructor in c++मैं कन्स्ट्रक्टरों में अपवादों को सही तरीके से कैसे संभाल सकता हूं?

मैं कैसे कंस्ट्रक्टर्स में अपवाद संभाल कर अगर मैं 6 वस्तुओं बनाने रहा हूँ और उन वस्तुओं 5 वस्तु बना सकते हैं और विफल रहता है, जबकि 6 बनाने?

धन्यवाद।

+3

लिंक के बारे में, अल्स आपको यहां देता है http://stackoverflow.com/questions/12723492/how-to-clean-initialized-resources-if-exception-thown-from-constructor-in-c? क्या यह सदस्य सदस्य वस्तुएं हैं? – ForEveR

+0

आपको किस हैंडलिंग की आवश्यकता है? आम तौर पर, आप बस अपवाद को प्रचारित करने देंगे, ताकि पहली 5 वस्तुओं को साफ तरीके से नष्ट कर दिया जा सके। कुछ और संदर्भ उपयोगी होंगे – jalf

+0

RAII। (Http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization) – ScaryAardvark

उत्तर

1

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

ध्यान दें कि विनाश आदेश निर्माण के विपरीत है। यही है, शरीर में साफ-सफाई पहले शुरू होती है जब सभी सबबोजेक्ट नहीं होते हैं, फिर भी नष्ट हो जाते हैं। फिर सदस्यों को नष्ट कर दिया जाता है, फिर गैर वर्चुअल बेस क्लास, और अंत में वर्चुअल बेस क्लासेस।

3

सामान्य व्यवहार केवल अपवाद प्रसार को छोड़ने के लिए है। किसी भी पूरी तरह से निर्मित बेस कक्षाओं और सदस्यों के लिए विनाशक कहा जाएगा; यदि पहली पांच वस्तुएं सदस्य हैं, तो वे सही ढंग से नष्ट हो जाएंगे।

एकमात्र मामला जहां समस्या हो सकती है, यदि आप ऑब्जेक्ट्स को गतिशील रूप से आवंटित किए गए हैं (new का उपयोग करके)। यदि वह है तो मामले: खुद से पूछने वाली पहली बात क्यों है? आप गतिशील रूप से आवंटित क्यों कर रहे हैं, और वस्तु को ठोस सदस्य नहीं बना रहे हैं? में मेरा अनुभव, कुछ विशेष मामलों (उदाहरण के लिए संकलन फ़ायरवॉल मुहावरे) को छोड़कर, इस तरह की आवश्यकता बहुत दुर्लभ है, इस मामले में, आमतौर पर कक्षा में बिल्कुल एक वस्तु होगी (उदाहरण के लिए एक सूचक कार्यान्वयन वस्तु)। ऐसे मामलों में, कोई समस्या नहीं है, क्योंकि उस ऑब्जेक्ट का new विफल रहता है, और कुछ भी नहीं किया गया है जिसके लिए पूर्ववत करना आवश्यक है।

आप असाधारण दुर्लभ मामले में अपने आप को मिल जाए जहाँ आप वास्तव में गतिशील आवंटन और का उपयोग करने के लिए क्या किया है एक से अधिक इस तरह के वस्तु (जैसे क्योंकि आप दो subobjects जो बहुरूपी होते हैं है), तो आप 'यह सुनिश्चित करना होगा कि प्रत्येक आवंटन कुछ में उप-ऑब्जेक्ट के प्रकार में लपेटा गया है (एक स्मार्ट सूचक चाल करेगा); एक बार पहले उप-ऑब्जेक्ट को सफलतापूर्वक बनाया गया है, तो इसका विनाशक होगा जिसे कन्स्ट्रक्टर कुछ बाद के बिंदु पर विफल कर देता है।

1

अपवादों से निपटने के "मूल" पर यह है कि लगभग सभी चीजों को विनाशकों के माध्यम से साफ किया जाना चाहिए। उदाहरण के लिए, यदि आप एक वस्तु "नया" करते हैं तो आपको "कच्चा" सूचक मिलता है; अगर कहीं अपवाद फेंक दिया जाता है तो आपको यह सुनिश्चित करना होगा कि यह कच्चा सूचक ठीक से "हटाएं" डी है - लेकिन सुनिश्चित करें कि आप कच्चे सूचक को हटा नहीं सकते हैं जिसे प्रारंभ नहीं किया गया है।

दूसरी तरफ, यदि आप उस पॉइंटर को std :: unique_ptr में संग्रहीत करते हैं तो आपको कुछ भी करने की ज़रूरत नहीं है; जब unique_ptr नष्ट हो जाता है तो ऑब्जेक्ट हटा दिया जाता है, और ऑब्जेक्ट-विनाश स्वचालित रूप से होता है: जब unique_ptr गुंजाइश से बाहर हो जाता है, तो संकलक क्लीनअप को आविष्कार करता है, पूरी तरह से अदृश्य (इसलिए क्लीनअप कॉल के साथ कोड-क्लटरिंग नहीं) और स्वचालित रूप से (इसलिए और नहीं 'आउच, जब यह उस दुर्लभ पथ को लेता है जिसे किसी ने वास्तव में परीक्षण नहीं किया है तो इसे साफ करना भूल जाता है')।

वही लगभग हर संसाधन पर लागू किया जा सकता है; COM-ऑब्जेक्ट्स (उदाहरण के लिए, डायरेक्टएक्स में उपयोग किए जाने के लिए) के लिए "ऑटो पॉइंटर्स" हैं, अधिकांश ढांचे आपको म्यूटेक्स के चारों ओर लपेटने के लिए "स्कोप्ड लॉक" -टाइप ऑब्जेक्ट देना चाहिए (इसलिए ऑब्जेक्ट बनने पर यह म्यूटेक्स को लॉक करता है, और जब इसे नष्ट किया जाता है तो इसे अनलॉक करता है), और आप विभिन्न विंडोज-हैंडल से निपटने के लिए छोटे रैपर लिख सकते हैं।

असल में, यदि आप अपने सभी सफाई को विनाशकों में डाल देते हैं, तो आपको साफ करने के लिए "कोशिश करें ... पकड़ो ... फिर से प्रयास करें"। और "बड़ी" वस्तुओं के विनाशक अक्सर बहुत ही सरल होंगे, क्योंकि लगभग सभी "निहित" वस्तुओं को उनके विनाशकों द्वारा स्वचालित रूप से साफ किया जाता है।

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

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