2011-11-29 7 views
34

मैंने एक नमूना कार्यक्रम चलाया और वास्तव में स्टैक-आवंटित वस्तुओं के लिए विनाशक कहा जाता है, लेकिन क्या यह मानक द्वारा गारंटीकृत है?क्या विनाशकों को सी ++ में फेंकने के बाद बुलाया जाता है?

+15

ज़रूर यह है। [आरए II] (http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization) है, जो सी ++ में सबसे महत्वपूर्ण मुहावरों में से एक है, इस पर निर्भर करता है। – Jon

+0

हां, यह अपवाद हैंडलिंग का पूरा बिंदु है। –

उत्तर

50

हाँ, यह गारंटी है (अपवाद प्रदान की पकड़ा है), आदेश जिसमें विनाशकर्ता लागू कर रहे हैं करने के लिए नीचे:

सी ++ 11 15.2 निर्माणकर्ता और विनाशकर्ता [except.ctor]

1 नियंत्रण एक हैंडलर को फेंक-अभिव्यक्ति से गुजरता है, इसलिए कोशिश करने वाले ब्लॉक के प्रवेश के बाद सभी स्वचालित ऑब्जेक्ट्स के लिए विनाशकों को बुलाया जाता है। स्वत: ऑब्जेक्ट्स उनके निर्माण के को पूरा करने के विपरीत क्रम में नष्ट हो जाते हैं।

इसके अलावा, अगर अपवाद वस्तु निर्माण के दौरान फेंक दिया जाता है, आंशिक रूप से निर्माण किया वस्तु के subobjects सही ढंग से नष्ट हो जाने की गारंटी है:

2 जिसका प्रारंभ या विनाश किसी भी भंडारण की अवधि का एक वस्तु एक अपवाद द्वारा समाप्त किया गया है अपने सभी पूर्णतः निर्मित उप-प्रोजेक्ट्स के लिए निष्पादित किया जाएगा ( यूनियन-जैसी कक्षा के संस्करण सदस्य को छोड़कर), जो कि के उप-प्रोजेक्ट्स के लिए है, जो मुख्य कन्स्ट्रक्टर (12.6.2) ने निष्पादन पूरा कर लिया है और विनाशक अभी तक निष्पादन शुरू नहीं किया है। इसी तरह, यदि किसी ऑब्जेक्ट के लिए गैर-प्रतिनिधि कन्स्ट्रक्टर निष्पादन पूरा कर चुका है और उस ऑब्जेक्ट के लिए कन्स्ट्रक्टर का प्रतिनिधि अपवाद अपवाद के साथ निकलता है, तो ऑब्जेक्ट के विनाशक को बुलाया जाएगा। यदि ऑब्जेक्ट को नई अभिव्यक्ति में आवंटित किया गया था, तो मेलिंग डेलोकेशन फ़ंक्शन (3.7.4.2, 5.3.4, 12.5), यदि कोई है, को ऑब्जेक्ट द्वारा कब्जा कर लिया गया संग्रहण मुक्त करने के लिए कहा जाता है।

इस पूरी प्रक्रिया के रूप में "तनाव मुक्त होने के ढेर" में जाना जाता है:

3 स्वत: वस्तुओं के लिए विनाशकर्ता बुलाने की प्रक्रिया का निर्माण एक थ्रो-अभिव्यक्ति के लिए एक कोशिश ब्लॉक से रास्ते पर "ढेर कहा जाता है अवांछित। "अगर एक विनाशक को के साथ अवांछित निकास के दौरान बुलाया जाता है, तो std :: terminate (15.5.1) कहा जाता है।

Resource Acquisition Is Initialization (RAII) नामक व्यापक रूप से उपयोग की जाने वाली तकनीक का आधार अनदेखा करना।

ध्यान दें कि अपवाद नहीं पकड़ा गया है, तो अनचाहे ढेर जरूरी नहीं है। इस मामले में यह कार्यान्वयन पर निर्भर करता है कि क्या अवांछित ढेर किया जाता है। लेकिन क्या स्टैक अनचाहे किया जाता है या नहीं, इस मामले में आपको std::terminate पर अंतिम कॉल की गारंटी है।

सी ++ 11 15.5.1 std :: समाप्त() फ़ंक्शन [except.terminate]

2 & hellip; ऐसी स्थिति में जहां कोई मिलान करने वाला हैंडलर नहीं मिला है, यह कार्यान्वयन-परिभाषित है कि std::terminate() से पहले स्टैक अवांछित है या नहीं।

+4

नोट: बाधित किसी ऑब्जेक्ट के निर्माण के संबंध में। ऑब्जेक्ट स्वयं नष्ट नहीं होता है (यह वास्तव में कभी नहीं रहता), गारंटी दी जाती है कि उप-वर्ग (बेस क्लास, विशेषताएँ) जिन्हें अब तक पूरी तरह से बनाया गया है, रिवर्स ऑर्डर में नष्ट हो जाएंगे। –

+0

बेकार अपवाद के लिए अवांछित (या नहीं) स्टैक के बारे में जानकारी जोड़ा गया। –

6

हाँ, विनाशकर्ता तनाव मुक्त होने के ढेर पर बुलाया जाने की गारंटी है, अपवाद के कारण तनाव मुक्त होने के फेंके जाने भी शामिल है। अपवादों के साथ केवल कुछ ही युक्तियां हैं जिन्हें आपको याद रखना होगा:

  • क्लास के विनाशक को इसके कन्स्ट्रक्टर में अपवाद डाला जाने पर कॉल नहीं किया जाता है।
  • अपवाद स्वचालित रूप से पुन फेंक दिया है, तो निर्माण प्रारंभ सूची कैच ब्लॉक में फंस जाता है।
+8

3) विनाशकों को कभी भी अपवाद फेंकना चाहिए, क्योंकि उन्हें पर्याप्त रूप से संभालने के लिए * नहीं * तरीका है। – DevSolar

+2

@DevSolar कुछ काउंटर-उदाहरण मौजूद हैं। –

+1

@ AlfP.Steinbach: किसी भी नाशक दौरान फेंक दिया ढेर-तनाव मुक्त (* एक और * अपवाद उत्पन्न होने के कारण) 'समाप्त होगा()' अपनी प्रक्रिया। मुझे काउंटर-उदाहरण देखने में दिलचस्पी होगी ... – DevSolar

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