2012-02-23 17 views
8

सी ++ में डायरेक्ट 3 डी का उपयोग करते समय मैं "क्यूब" कक्षा लिख ​​सकता हूं उदाहरण के लिए, जिसमें "ID3D11Buffer * vertexBuffer_" होता है और यह सुनिश्चित करता है कि उस क्यूब ऑब्जेक्ट के विनाशक vertexBuffer _-> रिलीज़() को कॉल करता है।डी भाषा में संसाधनों को मुक्त करना

मेरे पास एक "सीन" श्रेणी हो सकती है जिसमें "unique_ptr cube_" ऑब्जेक्ट होता है। इसलिए मुझे पता है कि जब मैं अपना दृश्य हटा दूंगा, तो घन हटा दिया जाएगा, और इसके परिणामस्वरूप डी 3 डी संसाधनों का उपयोग किया जा रहा है।

डी में मैं यह नहीं कर सकता। मैं विनाशकों को लिख सकता हूं लेकिन मुझे नहीं पता कि उन्हें कब बुलाया जाएगा। यदि जीसी को स्मृति की आवश्यकता नहीं है तो उन्हें कभी भी नहीं कहा जा सकता है ...

तो डी में इस तरह की चीज़ को संभालने का सबसे अच्छा तरीका क्या है? मैं उन सभी ऑब्जेक्ट्स में एक "नि: शुल्क" सदस्य फ़ंक्शन जोड़ सकता हूं जो अपने सभी संसाधनों को मुक्त करता है और किसी भी ऑब्जेक्ट पर "फ्री" कहता है, लेकिन ऐसा लगता है कि यह एक त्रुटि प्रवण मैनुअल ऑपरेशन और सी ++ से पीछे एक कदम है।

क्या डी में इस तरह की चीज़ को संभालने का कोई बेहतर तरीका है?

उत्तर

6

आप ढेर पर एक संरचना का उपयोग कर सकते हैं। कि में निर्धारवादी विनाश है। आप इसे std.typecons.RefCounted का उपयोग करके भी refcounted किया जा सकता है। ढेर पर एक संरचना का उपयोग न करें, भले ही आप यह गारंटी देना चाहते हैं कि विनाशक चलता है। फिलहाल, मुझे नहीं लगता कि अगर वे ढेर पर रखे जाते हैं तो structs के विनाशक कभी भी दौड़ते हैं, क्योंकि जीसी में ऐसी जानकारी नहीं होती है जिसे इसे करने की ज़रूरत होती है (जिसे किसी बिंदु पर तय किया जाना चाहिए हालांकि भविष्य)।

लेकिन अगर आप एक कक्षा में ढेर पर यह में डाल पर जोर देते हैं, और आप स्पष्ट रूप से वस्तु को नष्ट करना चाहते हैं, तो आप clear उस पर कॉल कर सकते हैं:

clear(obj); 

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

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

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

और अगर आप पागल महसूस कर रहे हैं, तो आप std.typecons.scoped है, जो शीघ्र ही हटा दिया करने के लिए प्रकार संशोधक scope बदल देता है (हालांकि scope अन्य संदर्भों में चारों ओर चिपके हुए है - जैसे scope के रूप में बयान) का उपयोग कर सकते हैं। यह ढेर पर एक वर्ग रखता है।लेकिन यह असुरक्षित है (यही कारण है कि scope इस संदर्भ में दूर जा रहा है), और यदि आप ऑब्जेक्ट को स्टैक पर चिपकाने जा रहे हैं तो शायद आप एक स्ट्रक्चर का उपयोग भी कर सकते हैं।

संपादित करें: तुम भी एक गैर जीसी आबंटित स्मृति का हिस्सा में वस्तु डाल करने के लिए की तरह आप C++ होगा malloc और std.conv.emplace साथ free इस्तेमाल कर सकते हैं, लेकिन मुझे लगता है कि आप स्पष्ट रूप से कॉल करने के लिए होगा कि इसे चलाने के लिए विनाशक, क्योंकि free विनाशकों के बारे में नहीं समझता है (यह एक सी कार्य है)। उसमें संसाधन के साथ स्मृति को दूर करने का लाभ होगा (जबकि जीसी ढेर पर किसी ऑब्जेक्ट पर clear का उपयोग करके ऑब्जेक्ट की सामग्री को नष्ट कर दिया जाएगा, स्मृति को मुक्त नहीं किया जाएगा), लेकिन मुझे नहीं पता कि यह आपको बहुत खरीदता है एक जीसी आवंटित वस्तु पर clear का उपयोग करने पर।

लेकिन, आप तो new के समान एक नि: शुल्क समारोह जो malloc और emplace आप के लिए करता है बना सकते हैं, और फिर delete के समान एक नि: शुल्क समारोह जो नाशक और free कहता है, जो आप सी के रूप में एक ही स्थिति देना होगा है ++ । वास्तव में, मुझे आश्चर्य है कि क्या यह मानक पुस्तकालय में इसे बनाने के लिए पर्याप्त उपयोगी होगा। शायद यह ऐसी चीज है जो कस्टम आवंटकों में समाप्त हो जाएगी। इसलिए, यह मुझे बिल्कुल भी आश्चर्य नहीं होगा अगर अपेक्षाकृत निकट भविष्य में, आप एक कस्टम संभाजक इस्तेमाल कर सकते हैं जैसे

auto obj = customAllocObj.create!MyObj(args); 
//Do stuff... 
customAllocObj.destroy(obj); 

कुछ करने के लिए और मुझे लगता है कि है कि काफी अच्छी तरह से यह देखते हुए कि कि अनिवार्य रूप से है आपकी समस्या का समाधान होगा लगता होगा एक ही चीज जो आपके पास सी ++ में होगी, बस अंतर्निहित new और delete के बजाय लाइब्रेरी फ़ंक्शंस के साथ। मुझे लगता है कि मैं इसे न्यूज ग्रुप पर लाऊंगा। मैं उम्मीद करता हूं कि कम से कम कुछ लोग हैं जो ऐसी सुविधा चाहते हैं, और यह कस्टम आवंटकों के साथ अच्छी तरह फिट बैठता प्रतीत होता है।

+0

व्यापक उत्तर के लिए धन्यवाद! मुझे यकीन नहीं है कि मैं ढेर पर एक संरचना का उपयोग कर सकता हूं क्योंकि मेरी वस्तुओं के जीवनकाल का जीवनकाल अधिक है। स्पष्ट मेरे लिए काम कर सकता है, लेकिन ऐसा लगता है कि यह मेरे अपने स्पष्ट() फ़ंक्शन से अलग नहीं है। Ypu ने मुझे किसी भी तरह के बारे में सोचने के लिए और अधिक चीज़ें दी हैं :) – jcoder

+0

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

2

बस स्पष्ट करने के लिए: विनाशक हमेशा कहा जाता है। यदि एप्लिकेशन बंद होने के समय तक किसी ऑब्जेक्ट को अंतिम रूप दिया नहीं गया है, तो जीसी इसके फाइनलाइज़र को चलाता है।

मुझे नहीं लगता कि कशेरुक बफर को हटाने के लिए मैन्युअल रूप से एक मुक्त() फ़ंक्शन को कॉल करने से C++ में मैन्युअल रूप से मेमोरी प्रबंधित करने की तुलना में कोई और त्रुटि प्रवण होती है। वैसे भी, आप देखना चाहते हैं: http://www.dlang.org/phobos/std_typecons.html#scoped और http://www.dlang.org/phobos/std_typecons.html#RefCounted

+2

समस्या यह है कि जब स्मृति को मुक्त किया जाता है तो विनाशकों को बुलाया जाता है जो भविष्य में किसी बिंदु पर होगा जब जीसी नोटिस करता है कि वस्तु को अब और संदर्भित नहीं किया गया है। मुझे तुरंत जारी होने के लिए डी 3 डी ऑब्जेक्ट्स की आवश्यकता है, भविष्य में कुछ अपरिभाषित बिंदु पर नहीं ... – jcoder

+0

['delete'] (http://www.d-programming-language.org/expression.html#DeleteExpression)? "यदि यूनरीएक्सप्रेस एक क्लास ऑब्जेक्ट संदर्भ है, और उस वर्ग के लिए एक विनाशक है, तो उस ऑब्जेक्ट इंस्टेंस के लिए विनाशक को बुलाया जाता है।" –

+0

'हटाएं' भाषा से हटाया जा रहा है। इसका इस्तेमाल न करें। आप 'clear' का उपयोग कर सकते हैं, जो ऑब्जेक्ट के विनाशक को कॉल करेगा और ऑब्जेक्ट को अमान्य कर देगा, लेकिन यह स्मृति को मुक्त नहीं करेगा। वह जीसी का काम है। यदि आप निर्धारवादी विनाश चाहते हैं, तो एक संरचना का उपयोग करें। –

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

  • कोई संबंधित समस्या नहीं^_^