2009-10-28 23 views
6

मैं मौजूदा पुस्तकालय पर काम करते समय विनाशक के अजीब उपयोग में आया था। एक स्टैक आवंटित एसएलएल वेक्टर के विनाशक को स्पष्ट रूप से कहा जा रहा था, जब उसके मामले को उस वस्तु को फिर से उपयोग करने की आवश्यकता हो सकती है। ये वेक्टर ऑब्जेक्ट्स एसएलएल वेक्टर क्लास का थोड़ा अनुकूलित संस्करण है जिसमें एक विशेष clear विधि है। विनाशक शरीर में दो विधि कॉल मौजूद हैं: clear(), _Tidy()सी ++ स्टैक आवंटित ऑब्जेक्ट, स्पष्ट विनाशक कॉल

मैं एक अच्छे कारण के बारे में सोचने की कोशिश कर रहा हूं कि इस विनाशक को केवल clear की बजाय क्यों बुलाया जा रहा है लेकिन मुझे नुकसान हुआ है। किसी ने भी कोई प्रकाश डाला है कि यह एक अच्छा विचार क्यों हो सकता है?

+0

क्या आप वैक्टर डाक्टर का कोड नमूना प्रदान कर सकते हैं, और इसे कैसे कहा जाता है? –

+3

_Tidy() क्या करता है? – Brian

+0

हमें दिखाएं कि वेक्टर कैसे बनाया गया था। – sbi

उत्तर

1

यह निश्चित रूप से एक अच्छा विचार नहीं है। विनाशक के चलते किसी ऑब्जेक्ट पर कोई भी ऑपरेशन अनिश्चित व्यवहार पैदा करता है।

+0

या इसके बजाय, विनाशक खत्म होने के बाद?मुझे लगता है कि यह मान्य हो सकता है यदि आप उदाहरण के साथ कुछ और करने से पहले और स्कोप से बाहर होने से पहले प्लेसमेंट के साथ एक ही स्थान पर एक और उदाहरण बनाते हैं। – UncleBens

+0

और इन परिचालनों में स्कोप के अंत में स्वचालित रूप से डाटर को शामिल किया जा रहा है। – sbi

+0

@UncleBens: नहीं, जैसे ही विनाशक शुरू होता है आपको अपने ऑब्जेक्ट पर अब विचार नहीं करना चाहिए ... मूल वर्ग के विनाशक से वर्चुअल फ़ंक्शंस का उपयोग करने का प्रयास करें जो वास्तव में व्युत्पन्न वर्ग की ढेर-आवंटित स्मृति का उपयोग करता है ... देखें मेरा मतलब :) ? –

5

क्या यह कक्षा किसी प्रकार की placement new विधि का उपयोग कर सकती है? यही एकमात्र समय है जब मैं उपयोग में स्पष्ट विनाशकों को देखता हूं।

+0

जब मैं लिख रहा था तो मुझे पंच पर मारो। ;) – John

1

हो सकता है कि मूल कोडर इस बात की परवाह करे कि वस्तुओं को स्मृति में आवंटित किया गया था।

फिर this discussion के अनुसार विनाशक को स्पष्ट रूप से बुलाया जाना चाहिए।

+0

शायद यह मामला है क्योंकि चर्चा एक स्टैक-आवंटित वेक्टर के बारे में है। –

5

बड़े वेक्टर?

जंगली अनुमान ... जब clear() कहा जाता है वेक्टर आमतौर पर खाली होता है लेकिन स्मृति जारी नहीं होती है। यही कारण है कि पैटर्न

std::vector<T>().swap(vector_to_clear); 

पुन: उपयोग करने के लिए वेक्टर को खाली करने और आवंटित स्मृति को साफ़ करने के लिए पैटर्न है।

शायद मूल लेखक पैटर्न को नहीं जानते थे और इस दुष्ट फैशन में आवंटित स्मृति से छुटकारा पाने की कोशिश की थी। (मुझे लगता है कि _Tidy आवंटित स्मृति को मुक्त करता है)

+0

वैक्टर आकार में भिन्न होते हैं लेकिन कोई भी बड़े पैमाने पर बड़ा नहीं होता है। मुझे इस पर मूल लेखकों के इरादे को जानना अच्छा लगेगा, और उम्मीद है कि यह सिर्फ एक गुमराह स्मृति स्मृति था – Colin

+0

मेरा पहला सवाल यह है कि: चेकइन टिप्पणी क्या है? – sbi

9

स्पष्ट() वास्तव में वेक्टर में आवंटित भंडारण को जारी करने की गारंटी नहीं है; एमएसवीसी कार्यान्वयन में _Tidy() वास्तव में उस भंडारण को मुक्त करेगा, इसलिए यह संभवतः अनुकूलन के रूप में किया गया था।

यह करने के लिए एक बुरा काम है, लेकिन आप इसे कानूनी रूप से (अपरिभाषित व्यवहार के बिना) कर सकते हैं जब तक भंडारण उसी प्रकार की वस्तु (सीवी-क्वालीफायर को अनदेखा कर) द्वारा पुन: उपयोग किया जाता है जो वास्तव में सभी स्टोरेज लेता है :

T automatic; 
automatic.T::~T(); 
new (&automatic) T(); 

सी ++ मानक की धारा 3.8.7 इस उपयोग परिदृश्य का वर्णन करती है और बताती है कि यह कानूनी कैसे है; इसमें एक उदाहरण भी शामिल है जो उपरोक्त के समान है।

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