2012-02-03 17 views
17

मैं सी ++ में आरएआईआई मुहावरे के बारे में सीख रहा हूं, और स्मार्ट पॉइंटर्स का उपयोग कैसे करें।जब कोई कन्स्ट्रक्टर अपवाद फेंकता है तो आरएआईआई कैसे काम करता है?

मेरी पढ़ाई में, मैं दो चीजों में आया हूं, मेरे लिए, एक-दूसरे से विरोधाभास प्रतीत होता है।

http://www.hackcraft.net/raii/ से उद्धरित:

... आरए II अर्थ विज्ञान के साथ एक सदस्य वस्तु बना दिया गया है, तो और निर्माता तो इसकी नाशक स्टैक के भाग के रूप बुलाया जाएगा पूरा कर लिया है पहले एक अपवाद होता है। इसलिए एक ऑब्जेक्ट जो एकाधिक संसाधनों को नियंत्रित करता है, वे अपने सफाई को गिनती कर सकते हैं भले ही यह सदस्य RAII ऑब्जेक्ट्स का उपयोग करके पूरी तरह से निर्मित नहीं किया गया हो।

लेकिन उद्धृत http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.10 से: एक निर्माता एक अपवाद फेंकता है तो

, वस्तु नाशक नहीं चला है। यदि आपकी ऑब्जेक्ट पहले से ही कुछ कर चुकी है जिसे पूर्ववत करने की आवश्यकता है (जैसे कुछ मेमोरी आवंटित करना, फ़ाइल खोलना, या सेमफोर लॉक करना), तो "सामान जो पूर्ववत करने की आवश्यकता है" को ऑब्जेक्ट के अंदर डेटा सदस्य द्वारा याद किया जाना चाहिए।

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

तो इन परिदृश्यों में वास्तव में क्या होता है?

+8

+1 यह तरीका है कि "newprogrammer [s]" * प्रश्न पूछना चाहिए! –

उत्तर

11

आप पहले उद्धरण को गलत समझ रहे हैं। यह मुश्किल नहीं है, क्योंकि यह भ्रमित है।

यदि आरएआईआई सेमेन्टिक्स के साथ कोई सदस्य ऑब्जेक्ट बनाया गया है और कन्स्ट्रक्टर पूरा होने से पहले एक अपवाद होता है तो इसके विनाशक को अवांछित ढेर के हिस्से के रूप में बुलाया जाएगा।

यही वह कहता है। यहाँ यह क्या मतलब है:

अगर आरए II अर्थ विज्ञान के साथ एक सदस्य वस्तु बना दिया गया है और एक अपवाद से पहले बाहरी वस्तु के निर्माता तो सदस्य वस्तु की नाशक होगा पूरा कर लिया है बाहरी वस्तु में होता है अवांछित ढेर के हिस्से के रूप में बुलाया जा सकता है।

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

class SomeType 
{ 
    InnerType val; 
public: 
    SomeType() : val(...) 
    { 
    throw Exception; 
    } 
}; 

जब आप एक SomeType उदाहरण बनाते हैं तो वह InnerType::InnerType कॉल करेगा:

यहाँ एक उदाहरण है। जब तक वह फेंक नहीं देता है, तब यह SomeType के निर्माता में प्रवेश करेगा। जब यह फेंकता है, तो यह val को नष्ट करने का कारण बनता है, इस प्रकार InnerType::~InnerType पर कॉल किया जाता है।

+1

आह जो समझ में आता है ... वैसे, क्या आप अद्भुत 3 डी ग्राफिक्स मार्गदर्शिका लिख ​​चुके हैं? मैं आपको धन्यवाद नहीं दे सकता कि गाइड कितना महान है। – newprogrammer

+3

"इससे इसके सभी सदस्यों के विनाशक को बुलाया जाएगा, लेकिन यह स्वयं का विनाशक नहीं होगा।" - ठीक है, सिर्फ अपवाद से पहले निर्माण पूरा करने वाले लोगों को फेंक दिया गया था .... –

2

ये दो बयान एक-दूसरे से विरोधाभास नहीं करते हैं, लेकिन पहले व्यक्ति की कुछ दुर्भाग्यपूर्ण भाषा है। जब किसी वस्तु का निर्माण फेंकता है, तो यह deconstructor नहीं कहा जाएगा, लेकिन उस वस्तु के स्वामित्व वाली सभी वस्तुओं को उनके व्यक्तिगत deconstructors द्वारा नष्ट कर दिया जाएगा।

तो आरएआईआई और स्मार्ट पॉइंटर्स के साथ किसी ऑब्जेक्ट के किसी भी पॉइंटर सदस्यों के लिए विनाशकों को ऑब्जेक्ट ऑब्जेक्ट के विनाशक से स्वतंत्र रूप से बुलाया जाएगा। कच्चे पॉइंटर्स वे जिस स्मृति को इंगित करते हैं उसे मुक्त नहीं करते हैं और मैन्युअल रूप से हटाए जाते हैं। मालिक के ऑब्जेक्ट के निर्माता को कच्चे पॉइंटर्स फेंक दिया जाना चाहिए। यह स्मार्ट पॉइंटर्स के साथ नहीं हो सकता है।

5

यहां कोई विरोधाभास नहीं है; विभिन्न संदर्भों में कुछ भ्रमित शब्दावली का उपयोग किया जा रहा है।

एक वस्तु के निर्माता एक अपवाद फेंकता है, तो निम्नलिखित होता है (अपवाद मानते हुए पकड़ा है):

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

नतीजतन, किसी भी संसाधन है कि स्मार्ट संकेत या अन्य आरए II वस्तुओं है कि डेटा वस्तु के सदस्यों वास्तव में साफ हो जाएगा विलुप्त की जा रही हैं, लेकिन विशेष कोड द्वारा प्रबंधित किया जाता वस्तु का नाशक में सफाई करने के लिए जीता आग नहीं

आशा है कि इससे मदद मिलती है!

+0

हां चरणबद्ध कदम से आपका कदम सबकुछ साफ कर दिया गया है! – newprogrammer