2012-05-15 10 views
7

आइए कहें कि मेरे पास दो स्थानीय वस्तुएं हैं। जब फ़ंक्शन वापस आता है, तो क्या यह गारंटी दी जाती है कि पहले कौन सा दायरा से बाहर निकल जाएगा?कॉलिंग विनाशक के आदेश और बिंदु

उदाहरण के लिए:

class MutexLock 
{ 
    /* Automatic unlocking when MutexLock leaves a scope */ 
    public: 
     MutexLock (Mutex &m)  { M.lock(); } 
     ~MutexLock(Mutex &m)  { M.unlock(); } 
}; 

यह एक बहुत ही आम है जब क्षेत्र से बाहर जाने पर आप स्वत म्युटेक्स जारी करने के लिए इस्तेमाल किया चाल है:

मैं इस तरह एक वर्ग है। लेकिन अगर मुझे दायरे में दो म्यूटेक्स चाहिए तो क्या होगा?

void *func(void *arg) 
{ 
    MutexLock m1; 
    MutexLock m2; 

    do_work(); 

} // m1 and m2 will get unlocked here. But in what order? m1 first or m2 first? 

यह वास्तव में किसी भी डेडलॉक का कारण नहीं बन सकता है। लेकिन ऐसे कई उदाहरण हो सकते हैं जिनमें संसाधन जारी करने का आदेश उपयोगकर्ता के लिए उपयोगी हो सकता है। उस मामले में विनाशकों पर भरोसा करने के बजाय स्पष्ट होना महत्वपूर्ण है?

इसके अलावा, किसी भी मामले में संकलक द्वारा विनाश में देरी हो सकती है? क्या मेरा मतलब है

func() 

{ 

    { 
     foo f(); 
    } ---------> Can compiler choose to not destroy f here, rather do it at the time when func() is returning. 
} 

उत्तर

10

// m1 and m2 will get unlocked here. But in what order? m1 first or m2 first?

विनाशकर्ता निर्माण के विपरीत क्रम में कहा जाता हो जाएगा: m2 तो m1

उस मामले में विनाशकों पर भरोसा करने के बजाय स्पष्ट होना महत्वपूर्ण है?

विनाश का आदेश अच्छी तरह से निर्दिष्ट है ताकि आप इस पर भरोसा कर सकें।

इसके अलावा, किसी भी मामले में संकलक द्वारा विनाश में देरी हो सकती है?

नहीं। अगर ऐसा हुआ, कि RAII आधारित कोड का एक बहुत टूट जाएगा (अपने MutexLock वर्ग का एक बहुत अच्छा उदाहरण है)।

+1

@ एक्स के उत्तर के पहले भाग का समर्थन करने के लिए, यह मानक (ड्राफ्ट संस्करण, दिनांक: 2006-11-06 --- का एक अंश है - यह पहलू बाद के संस्करणों में नहीं बदला गया है। स्पष्टता के लिए छोड़े गए अनुभागों के संदर्भ): "एक दायरे से बाहर निकलने पर (हालांकि पूरा किया गया), विनाशकों को स्वचालित रूप से भंडारण अवधि (नामित वस्तुएं या अस्थायी) के साथ सभी निर्मित वस्तुओं के लिए बुलाया जाता है, जिन्हें उनकी घोषणा के विपरीत क्रम में घोषित किया जाता है।" बेशक आपके उदाहरण में स्वचालित परिवर्तनीय घोषणाएं शामिल हैं। – sturmer

2

विनाश निर्माण के विपरीत क्रम में होता है: पहले m2 तब m1

कंपाइलर कभी भी स्कोप एंड (}) के पीछे ऑब्जेक्ट के जीवनकाल में देरी नहीं कर सकता है।

0

जब यह दायरे से बाहर हो जाता है तो ऑब्जेक्ट हमेशा नष्ट हो जाता है - यह जावा नहीं है। एफ नष्ट हो जाएगा जहां आप संकेत देते हैं और func के अंत में कभी नष्ट नहीं किया जाएगा। आम तौर पर विनाशकों को उनके निर्माण के आदेश के विपरीत क्रम में बुलाया जाता है।

4

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


इसके अलावा, विनाश किसी भी मामले में संकलक की देरी हो सकती है?
सं।
कंपाइलर RAII का उद्देश्य नहीं कर सकता है। यह प्रोग्रामर के हिस्से पर किसी भी स्पष्ट मैन्युअल प्रयास के बिना & संसाधनों को निर्विवाद रूप से साफ करने के लिए तंत्र प्रदान करता है।
विनाश में देरी की आपकी आवश्यकता आरएआईआई के बहुत ही उद्देश्य के समानांतर है, यह मैनुअल संसाधन प्रबंधन के लिए कॉल करती है।
यदि आपको मैन्युअल संसाधन प्रबंधन की आवश्यकता है तो आप new के माध्यम से ढेर पर आवंटित पॉइंटर्स रख सकते हैं और उनके द्वारा इंगित ऑब्जेक्ट्स तब तक वैध होंगे जब तक कि आप उन्हें delete कॉल और ऑर्डर जिसमें आप उन्हें कॉल करते हैं, के माध्यम से स्पष्ट रूप से उन्हें रोक दें।
बेशक, यह न ही सलाह दी जाती है और न ही ऐसा करने के लिए प्रोत्साहित किया जाता है।

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