2011-02-08 8 views
11

मैं एक C++/CLI विधानसभा में एक प्रबंधित वस्तु है। सी ++/सीएलआई होने के नाते, यह अपने "विनाशक" के माध्यम से डिस्पोजेबल पैटर्न लागू करता है (हाँ, मुझे पता है कि यह एक मानक सी ++ विनाशक के समान नहीं है)। सी ++/सीएलआई से, मैं बस delete ऑब्जेक्ट होगा। हालांकि, मैं इस ऑब्जेक्ट को सी # कक्षा में सदस्य चर के रूप में उपयोग कर रहा हूं।मैं सी # से प्रबंधित सी ++/सीएलआई ऑब्जेक्ट का निर्धारण कैसे कर सकता हूं?

मेरी सी # वर्ग से, तो, मैं C++/CLI वस्तु जब मैं इसे का उपयोग करना समाप्त कर रहा हूँ पर निपटान() विधि के बराबर कॉल करना चाहते हैं। चूंकि यह (और होना चाहिए) वर्ग का सदस्य चर है, इसलिए उपयोग() ब्लॉक का उपयोग करने से सवाल का सवाल है। जहां तक ​​मैं कह सकता हूं, सी ++/सीएलआई के अलावा किसी अन्य भाषा से संसाधनों के प्रत्यक्ष, निर्धारिक निपटान के लिए कोई खुलासा नहीं है। मैं यह कैसे हासिल कर सकता हूं?

+0

मुझे समझ में नहीं आता है कि ['निपटान'] (http://msdn.microsoft.com/en-us/) में क्या गलत है लाइब्रेरी/system.idisposable.dispose.aspx) विधि? आप इसके बिना डिस्पोजेबल पैटर्न को कार्यान्वित नहीं कर सकते हैं। –

+1

सी ++/सीएलआई कक्षा 'निपटान()' विधि का पर्दाफाश नहीं करती है। यह C++/CLI नाशक की तरह वाक्य रचना में निहित है (उदा। '~ MyClass'), लेकिन जब सी # से वस्तु को संदर्भित, आप एक संपर्क में' निपटान() 'विधि की जरूरत नहीं है, के रूप में पास के रूप में मैं बता सकते हैं। – JimEvans

उत्तर

9

C++/CLI नाशक की तरह वाक्य रचना स्वचालित रूप से IDisposable लागू करता है, लेकिन यह एक तरह से सी # के explicit interface implementation के समान वृद्धि हो। इसका मतलब है आप Dispose विधि का उपयोग करने के IDisposable को कास्ट करने के लिए होगा:

((IDisposable)obj).Dispose(); 
+3

घर पर यह न करें: आप निपटान विधि को कॉल करने के बजाय खाली 'उपयोग' कथन का उपयोग कर सकते हैं: '(obj) का उपयोग करना; '। लेकिन कृपया, बच्चों के बारे में सोचो। –

+0

मैं इसे उत्तर के रूप में स्वीकार कर रहा हूं, भले ही यह वास्तव में नहीं है। सवाल स्वयं एक वैध सवाल नहीं है; समस्या मेरे सी ++/सीएलआई कोड में थी। मैं एक अमूर्त वर्ग के कार्यान्वयन का उपयोग कर रहा था, लेकिन फैक्ट्री विधि से अमूर्त बेस क्लास लौटा रहा था, और बेस क्लास ने विनाशक को लागू नहीं किया था, और इस प्रकार कोई खुलासा निपटान() विधि नहीं थी। – JimEvans

-2

आप नहीं कर सकते। कम से कम, सी # से नहीं। कचरा कलेक्टर अपनी नौकरी करते हैं।

+0

निश्चित रूप से आप कर सकते हैं। सी # इसके लिए एक कीवर्ड भी है। –

+0

* निर्धारित रूप से? * वह कौन सा कीवर्ड है? (गंभीरता से। मैं जानना चाहता हूं।) –

+1

'उपयोग' कथन संसाधनों के निर्धारिक निपटान की अनुमति देने के लिए बनाया गया था। –

9

यह C++/CLI में तो स्पष्ट नहीं है, लेकिन यह काम करता है बिल्कुल जिस तरह से यह सी # में करता है। जब आप ऑब्जेक्ट ब्राउज़र के साथ कक्षा को देखते हैं तो आप इसे देख सकते हैं। या ildasm.exe जैसे एक डिकंपेलर, यह देखने के लिए सबसे अच्छा तरीका है कि यह क्या करता है।

जब आप नाशक लिखना तो C++/CLI संकलक कोड का एक समूह ऑटो उत्पन्न करता है। यह डिस्पोजेबल पैटर्न लागू करता है, आपकी कक्षा स्वचालित रूप से IDISposable लागू करती है, भले ही आपने इसे इस तरह घोषित नहीं किया हो। और आपको एक सार्वजनिक निपटान() विधि, संरक्षित निपटान (बूल) विधि और जीसी :: SuppressFinalize() को स्वचालित कॉल मिलता है।

आप C++/CLI में delete का उपयोग स्पष्ट रूप से इसे लागू करने की, संकलक एक निपटान() कॉल उत्सर्जन करता है। और तुम ढेर अर्थ विज्ञान का उपयोग करके C++/CLI में आरए II के बराबर मिलता है, संकलक स्वचालित रूप से गुंजाइश ब्लॉक के अंत में निपटान कॉल उत्सर्जन करता है। सिंटेक्स और व्यवहार जो सी ++ प्रोग्रामर से परिचित है।

आप बिल्कुल वही चीज़ आप सी # में क्या चाहते हैं, तो वर्ग है | सी # में लिखा गया है। आप स्पष्ट रूप से आह्वान करने के लिए निपटान() को कॉल करते हैं, आप using कथन का उपयोग अपवाद-सुरक्षित तरीके से इसे स्पष्ट रूप से करने के लिए करते हैं।

वही नियम अन्यथा लागू होते हैं, आप केवल को को विनाशक की आवश्यकता होती है जब आपको कुछ ऐसी स्मृति रिलीज़ करने की आवश्यकता होती है जो प्रबंधित स्मृति नहीं है। लगभग हमेशा एक मूल वस्तु, जिसे आप कन्स्ट्रक्टर में आवंटित करते हैं। इस बात पर विचार करें कि अगर यह अप्रबंधित वस्तु छोटी है तो यह परेशान नहीं हो सकता है और जीसी :: AddMemoryPressure() एक बहुत ही सभ्य विकल्प है। हालांकि आपको इस तरह के एक रैपर वर्ग में फाइनलाइज़र (!ClassName()) को लागू करना होगा। आप निपटान() को कॉल करने के लिए बाहरी क्लाइंट कोड को मजबूर नहीं कर सकते हैं, ऐसा करना वैकल्पिक है और इसे अक्सर भुला दिया जाता है। आप इस तरह की निगरानी को एक अप्रबंधित स्मृति रिसाव का कारण नहीं बनना चाहते हैं, फाइनल सुनिश्चित करता है कि यह अभी भी जारी है। आम तौर पर विनाशक को लिखने का सबसे आसान तरीका है अंतिम रूप से अंतिम रूप (this->!ClassName();)

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