2012-04-02 12 views
9

This answer उद्धरण सी ++ 11 स्टैंडर्ड 3.8:सी ++ 11 में एक साइड इफेक्ट अपरिभाषित व्यवहार के साथ एक ऑब्जेक्टर को नष्ट करने वाला ऑब्जेक्ट क्यों नहीं हटा रहा है?

अगर वहाँ नाशक करने के लिए या तो एक हटाने अभिव्यक्ति (5.3.5) भंडारण जारी करने के लिए नहीं किया जाता है कोई स्पष्ट कॉल है, नाशक नहीं होगा निहित रूप से बुलाया गया और कोई भी प्रोग्राम जो कि विनाशक द्वारा उत्पादित पक्ष ई एफएफ ईक्ट्स पर निर्भर करता है, में अवांछित व्यवहार है।

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

प्रोग्राम व्यवहार अब अपरिभाषित क्यों है? साइड इफेक्ट्स क्यों नहीं छोड़े जाएंगे (क्योंकि विनाशक को नहीं कहा जाता है) और कार्यक्रम सामान्य रूप से बिना साइड इफेक्ट्स के लागू होता है?

+2

दिलचस्प सवाल। लेकिन जब कोई व्यक्ति की आवश्यकता नहीं होती है तो कोई वस्तु पर विनाशक को क्यों नहीं बुलाएगा? – ereOn

+1

यदि इस मामले में विनाशक पूर्व के लिए गैर-छोटे कार्यों को निष्पादित करता है: बंद संसाधन संसाधन संभालता है या कुछ मान्य आदि को स्थिति सेट करता है, तो विनाशक को बुलाया नहीं जा रहा है कार्यक्रम का असर होगा और परिणामस्वरूप अपरिभाषित व्यवहार होगा। मैं तर्क को समझ नहीं पा रहा हूं साइड इफेक्ट्स छोड़ने के लिए। –

+0

@ereOn: सिंगलेट्स का उपयोग एक केस के रूप में किया गया है (हालांकि, हालांकि इसे अच्छा डिजाइन नहीं माना जाना चाहिए)। –

उत्तर

5

महत्वपूर्ण बात यह है कि पैरा (जोर मेरा) का पहला हिस्सा है:

एक कार्यक्रम से किसी भी वस्तु का जीवन समाप्त कर सकते हैं भंडारण जो वस्तु पर पुन: उपयोग ...

यदि आप किसी ऑब्जेक्ट के लिए स्टोरेज का पुन: उपयोग करते हैं जिसका विनाशक नहीं कहा जाता है, तो आपको अपरिभाषित व्यवहार मिलता है। उदाहरण के लिए, ऑब्जेक्ट थ्रेड शुरू कर सकता था, या कॉलबैक पंजीकृत कर सकता था, या कुछ अन्य क्रिया जहां बाहरी घटक ऑब्जेक्ट को अभी भी मौजूद होने की उम्मीद कर सकता था।

+2

मैं असहमत हूं। पूर्ण उद्धरण * या एक गैर-तुच्छ विनाशक * के साथ कक्षा प्रकार के किसी ऑब्जेक्ट के लिए विनाशक को स्पष्ट रूप से कॉल करके * जोड़ता है। इसलिए इस मामले में विनाशक को बुलाया जाएगा। –

+0

क्षमा करें, किस मामले में? यह ** या ** कहता है, इसलिए मेरा उद्धरण ऊपर और साथ ही आपके सामने खड़ा प्रतीत होता है। –

+0

लेकिन यह वह मुद्दा है जिस पर मैं इशारा कर रहा हूं। न तो उद्धरण * अपने ही * पर खड़ा है। मानक एक विकल्प देता है, लेकिन पसंद हमारा नहीं है। * एक गैर-तुच्छ विनाशक के साथ एक वर्ग प्रकार की वस्तु के लिए * ** या ** की दो शाखाओं के बीच चयन करने के लिए मानदंड देता है। और इसलिए एक गैर-तुच्छ विनाशक (जो यहां दिलचस्प मामला है) वाला कोई भी वस्तु अपने विनाशक को * पहले * इसके भंडारण का पुन: उपयोग करने के लिए बुलाएगा। –

1

आपका प्रश्न समझ में नहीं आता है।

साइड इफेक्ट्स क्यों छोड़े जाएंगे (क्योंकि विनाशक को नहीं कहा जाता है) और कार्यक्रम सामान्य रूप से बिना साइड इफेक्ट्स के लागू होता है?

वे छोड़े गए हैं, क्योंकि वे विनाशक द्वारा ट्रिगर किए गए थे और इसे नहीं कहा गया है।

के मेरे पढ़ने:

और किसी भी प्रोग्राम है जो पक्ष ई एफएफ नाशक द्वारा उत्पादित ECTS पर निर्भर करता है unde फाई नेड व्यवहार है।

सरल है, मैं इसे आरएआईआई के प्रकाश में देखता हूं। उदाहरण:

#include "Object.hpp" 

struct Manager: private boost::noncopyable { 
    union Raw { 
    char _[sizeof(Object)]; 
    Object o; 
    }; 
    static Raw raw; 

    Manager() { new (raw.o) Object(); } 
    ~Manager() { raw.o.~Object(); } 
}; 

अब, अगर मैं एक Manager आवंटित, इसे नष्ट करने के लिए भूल जाता है, और एक नया आबंटित करता है, मैं एक चुटकी मैं एक दूसरे से एक के साथ पहली बार बनाया Object के भंडारण को अधिलेखित करने के लिए कर रहा हूँ, भले ही में हूँ यह अभी भी "जीवित" है। यह अपरिभाषित व्यवहार है।

1

मेरा मानना ​​है कि यह कचरा संग्रह की अनुमति देने के लिए मानक में डाल दिया गया है। और यह इंगित करने के लिए कि सी ++ अलग-अलग व्यवहार करता है, कुछ अन्य भाषाओं को इकट्ठा करते समय विनाशकों को बुलाकर नहीं।

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

यदि यह विनाशकों पर निर्भर नहीं है, तो सब ठीक है।

3

इस मामले में, हमारे पास एक सटीक उत्तर है। विशिष्ट लाइन को CWG 1116, "यूनियन सदस्यों के एलिसिंग" को हल करने के लिए पेश किया गया था।