2011-01-19 17 views
26

आने वाले सी ++ 0x मानक में, क्या होता है जब चालक कन्स्ट्रक्टर के भीतर/उसके दौरान कोई अपवाद फेंक दिया जाता है?सी ++ ले जाएं अर्थशास्त्र और अपवाद

क्या मूल वस्तु बनी रहेगी? या एक अनिर्धारित स्थिति में मूल और चाल-वस्तु दोनों हैं? भाषा द्वारा गारंटी दी गई गारंटी क्या है?

+0

मैं अगर यह नाशक जहां यह सिर्फ एक बुरी चीज़ है अगर यह एक अपवाद फेंकता की तरह है सोच रहा हूँ एक जंगली जानवर हैं। मुझे लगता है कि ज्यादातर मामलों में आप कभी भी ऐसा कुछ भी कर सकते हैं जो फेंक सकता है, क्योंकि आप (आमतौर पर) बस पॉइंटर्स को चारों ओर ले जा रहे हैं ... – templatetypedef

+3

तो आप क्या कह रहे हैं कि कोई अपवाद नहीं होना चाहिए फेंक दिया जा रहा है क्योंकि सदस्यों की राज्य की प्रतिलिपि बनाई जा रही है, कभी भी चालन अभियान के दौरान उत्परिवर्तित नहीं किया जाता है? –

+2

सॉर्टा- यह आपके द्वारा उपयोग किए जाने वाले अपरिवर्तनीय तर्क के समान है कि 'स्वैप' फेंक नहीं सकता है। आधारभूत मामले के रूप में, आदिवासियों को फिर से सौंपना और प्रतिलिपि बनाना कभी नहीं फेंकता है। एक अपरिवर्तनीय कदम के रूप में, कुछ डेटा सदस्यों के साथ किसी ऑब्जेक्ट के लिए एक चालक कन्स्ट्रक्टर उन डेटा सदस्यों को फेंकने के बिना स्थानांतरित कर सकता है (अपरिवर्तनीय परिकल्पना!), और इसलिए फेंकने के बिना खुद को स्थानांतरित कर सकते हैं। स्वतंत्र रूप से, हालांकि, मैं अभी भी जानना चाहता हूं कि आपके प्रश्न का सही उत्तर क्या है। – templatetypedef

उत्तर

3

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

ऑब्जेक्ट को स्थानांतरित करने के लिए, यह वर्तमान सी ++ में एक सीटीआर से फेंकने जैसा ही है: किसी भी निर्मित अड्डों और सदस्यों को नष्ट कर दें, सीटीओआर के फ़ंक्शन को हैंडलर को निष्पादित करें, यदि कोई है, तो अपवाद का प्रचार करें। विवरण N3225 §15.2p2 में हैं।

विशेष रूप से, ध्यान दें कि कंटेनरों की आवश्यकता होती है उनके संभाजक प्रकार चाल ctors फेंकने की जरूरत नहीं:

संभाजक के इस तरह के कदम निर्माण एक अपवाद के माध्यम से बाहर निकलने नहीं किया जाएगा। [N3225 §23.2p8]

इस कंटेनर के आसपास allocators ले जाएँ और एक अपवाद के मामले में अपने आइटम को साफ करने के लिए जब चलती या आइटम की प्रति बनाने उन allocators उपयोग करने के लिए अनुमति देता है।

10

मेरा मानना ​​है कि मानकों की समिति ने मूल रूप से इसे बनाने के लिए रचनाकारों को अपवादों को फेंकने की अनुमति नहीं दी जाएगी, लेकिन (कम से कम आज तक) ने पाया कि इसे लागू करने की कोशिश करने में बहुत अधिक समस्याएं थीं।

प्रस्ताव एन 3050, "मूव कन्स्ट्रक्टर्स टू थ्रो (रेव 1)" को अनुमति देना, ड्राफ्ट मानक में शामिल किया गया है। अनिवार्य रूप से प्रस्ताव कन्स्ट्रक्टरों को फेंकने की क्षमता को जोड़ता है, लेकिन कुछ संचालनों के लिए 'फेंकने' चालों को अस्वीकार करने की अनुमति देता है जहां मजबूत अपवाद सुरक्षा गारंटी की आवश्यकता होती है (लाइब्रेरी ऑब्जेक्ट की प्रतिलिपि बनाने के लिए वापस आ जाएगी यदि कोई फेंकने वाला कदम नहीं है ' टी उपलब्ध)।

यदि आप एक चालक कन्स्ट्रक्टर को गैर-फेंकने (noexcept) के रूप में चिह्नित करते हैं और एक अपवाद फेंक दिया जाता है, तो std :: terminate() को कॉल किया जाएगा।

यह भी मुद्दों है कि N3050 को संबोधित करना था पर चर्चा करता है कि दाऊद इब्राहीम से एक ब्लॉग लेख को पढ़ने के लायक हो सकता है:

+0

डेविड अब्राहम के लेख के लिए धन्यवाद :) –

+3

हां, मुझे भी पूरी सीपीपी-अगली ब्लॉग साइट बेकार लेखों पर काफी रोचक ढेर मिली! –

2

आपका सवाल तब अपवाद गारंटी के बारे में एक प्रश्न के बराबर है। 3 प्रकार की अपवाद गारंटीएं हैं (जो फ़ंक्शंस पर लागू होती हैं):

  • बिल्कुल अपवाद गारंटी नहीं (वास्तव में एक प्रकार नहीं ...लेकिन यह भी हो सकता है यदि कोई चिंता बात को दिया जाता है)
  • बेसिक अपवाद गारंटी: तकनीकी रूप से सही है, लेकिन कार्यात्मक सही नहीं (यानी कोई संसाधन लीक कर रहा है, इस कार्यक्रम अचानक पड़ाव के बिना समाप्त कर देगा, लेकिन यह अवांछित हो सकता है साइड इफेक्ट्स, जैसे कि भुगतान किया जा रहा है, लेकिन कमांड पंजीकृत नहीं है)
  • मजबूत अपवाद गारंटी: सभी या कुछ भी नहीं (लेनदेन की तरह), या तो सब कुछ ठीक हो गया है, या हम पिछले के लिए रोलबैक राज्य।
  • कोई फेंक अपवाद गारंटी: यह कभी फेंक नहीं देता है, इसलिए कोई चिंता नहीं है।

जब आप अपना कार्य लिखते हैं, तो आप आमतौर पर मौजूदा कार्यों को अपनी गारंटी के साथ उठाते हैं। अपवाद गारंटी को बढ़ाना मुश्किल है, यह आमतौर पर उपयोग की जाने वाली कमजोर गारंटी से सीमित है।

W.r.t आपका प्रश्न, कम से कम मजबूत अपवाद गारंटी मूल ऑब्जेक्ट को अपवादित होने पर छोड़ा जाने वाला मूल ऑब्जेक्ट छोड़ने के लिए लेता है।

तो, क्या होता है यदि चाल-निर्माण के दौरान कोई अपवाद फेंक दिया जाता है? यह गारंटी देता है subobjects और जिस तरह से आप कॉल संयुक्त द्वारा प्रदर्शित पर निर्भर करता है ...

  1. एक अपवाद है, एक निर्माता से फेंक दिया जाता है वस्तु नहीं बनाया जा रहा है और सभी का निर्माण किया subobjects नष्ट कर रहे हैं, तो में उल्टे क्रम। यह नियम एक चालक-निर्माता
  2. पर भी लागू होता है जब तक कि आप कन्स्ट्रक्टर को कोशिश करने में "लपेटें" नहीं देते हैं और किसी भी तरह से स्थानांतरित किए गए ऑब्जेक्ट को पुनर्स्थापित करते हैं, तो वे अपने संसाधन खो देंगे। ध्यान दें कि वे अभी भी एक विनाशकारी स्थिति में होना चाहिए, इसलिए तकनीकी रूप से कार्यक्रम सही होगा।

अपवाद की गारंटी देता है के संदर्भ में, इसका मतलब है कि डिफ़ॉल्ट रूप से, subobjects 'कंस्ट्रक्टर्स के सभी कम से कम बेसिक अपवाद गारंटी को पूरा है, तो अपनी चाल निर्माता होगा भी, किसी भी विशेष देखभाल के बिना।

हालांकि, यहां तक ​​कि अगर सब subobjects 'कंस्ट्रक्टर्स मजबूत अपवाद गारंटी पूरा बहुत संभव है कि आप अपने खुद के चाल निर्माता यह पूरा होने में सफल हो जाएगा: यह एक ही मुद्दा है कि लेन-देन चेनिंग एक सौदे उपज नहीं है।

तो subobjects 'निर्माताओं की केवल एक ही फेंक सकता है, और यह मजबूत अपवाद गारंटी को पूरा करती है, तो अपनी चाल निर्माता स्वाभाविक रूप से यह अपने आप को पूरा करेगा अगर तुम फेंक वस्तु पहले आरंभ कर देगा।

आशा इस मदद की ... अपवाद को वश में करने :)

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