2014-07-03 8 views
5

एक सहकर्मी ने निम्नलिखित कोड लिखा, जिसे मैं आश्वस्त हूं, गलत है।एक निर्माता के इस उपयोग के लिए शब्दावली क्या है?

मैं उसे करने के लिए समस्याओं व्याख्या करना चाहते हैं, लेकिन उचित शब्द पता नहीं है, तो मैं संदर्भ मेरी स्थिति का समर्थन करने के नहीं मिल सकता है:

उनकी कोड:

BSTR someString = _bstr_t(L"Hello World"); 

क्यों मुझे लगता है कि यह गलत है:
मेरा मानना ​​है कि _bstr_t(L"Hello World");_bstr_t के लिए निर्माता को कॉल करता है, और उस प्रकार का एक अल्पकालिक अस्थायी चर बनाता है। वह अस्थायी स्वचालित रूप से हटा दिया जाएगा, और कोड की इस पंक्ति के बाद (अर्ध-कॉलन अनुक्रम बिंदु के बाद) इसकी स्ट्रिंग-स्पेस मुक्त हो जाती है।
यह someString छोड़ देगा जो स्मृति को इंगित करता है।

सवाल:
एक निर्माता की है कि कॉल के लिए उचित शब्द क्या है?

क्या आप कुछ संदर्भ/नियम/पृष्ठों को इंगित कर सकते हैं जो विस्तार से विस्तार का वर्णन करते हैं?

क्या अस्थायी _bstr_t ऑब्जेक्ट का कोई शब्द है?
मुझे लगता है कि मैं इसे "अज्ञात, अस्थायी चर" कहूंगा, लेकिन मुझे नहीं पता कि यह तकनीकी रूप से सटीक है या नहीं।

(या शायद मैं अपने विश्लेषण में पूरी तरह से गलत हूँ .... यदि हां, तो मैं जानकर प्रसन्नता होगी)


स्पष्टीकरण के लिए:,

_bstr_t is a C++ class सामान्यतः माइक्रोसॉफ्ट द्वारा अपने बीएसटी प्रकार को लपेटने के लिए उपयोग किया जाता है, इसलिए इसमें रचनाकार/विनाशक/ऑपरेटर आदि हैं।

BSTR एक टाइपिफ़ है बस एक WCHAR*, इसलिए इसमें कोई तर्क नहीं है। यह सिर्फ एक गूंगा सूचक है।

उत्तर

3

कोड सवाल

BSTR someString = _bstr_t(L"Hello World"); 

में एक conversion constructor call जो पारित कर दिया wchar_t[] का उपयोग कर एक bstr_t उदाहरण बनाता है कर रही है। यह स्वयं ही ठीक है।

someFunction(_bstr_t(L"Hello World")); // OKAY 

और यह ठीक हो क्योंकि अस्थायी पूरे बयान के अंत तक बच जाएगा होगा: उदाहरण के लिए यदि आप एक समारोह BSTR को स्वीकार फोन और एक स्ट्रिंग शाब्दिक वहाँ में आप आसानी से ऐसा कर सकता है पारित करने के लिए चाहते थे जो समाप्त होता है जहां अर्धविराम रहता है (इस प्रकार सी ++ अस्थायी काम करते हैं)।

हालांकि सवाल में कोड ठीक क्योंकि _bstr_t उदाहरण तो एक BSTR उदाहरण दृष्टांत के लिए जो अस्थायी (अस्थायी अर्धविराम और BSTR में नष्ट हो जाता है से अधिक समय रहता है (कक्षा bstr_t में रूपांतरण ऑपरेटर का प्रयोग करके) प्रयोग किया जाता है नहीं है सूचक someString उससे परे अच्छी तरह से रहता है)। तो आपको एक खतरनाक BSTR पॉइंटर someString मिलता है जिसका उपयोग अपरिभाषित व्यवहार की ओर जाता है। यह तब भी काम कर सकता है जब ओएलई ढेर प्रक्रिया पता स्थान में मैप किए गए स्ट्रिंग के लिए उपयोग की गई स्मृति को रखने के लिए चुनता है।

class _bstr_t कार्यान्वयन (विंडोज एसडीके में फ़ाइल comutil.h) साथ आपूर्ति की है, ताकि आप अपने डीबगर के साथ कोड में कदम और देखो यह है कि एक SysAllocString() कॉल जब अस्थायी बनाई गई है और फिर एक SysFreeString() कॉल जब यह नष्ट हो जाता है कर सकते हैं और कोड अगली पंक्ति में पहुंचने से पहले होता है। इसलिए ओएलई ढेर में स्ट्रिंग ऑब्जेक्ट को अगली पंक्ति में कोड प्राप्त होने से पहले हटा दिया जाता है और someString पॉइंटर प्रश्न में कोड के तुरंत बाद लटक रहा है। मुझे लगता है कि यह सबसे संदिग्ध व्यक्ति को भी मनाने के लिए पर्याप्त होगा।

तो हाँ, आप सही हैं कि कोड गलत है। सही कोड होगा:

_bstr_t someString(L"Hello World"); 
+0

धन्यवाद, शब्द "रूपांतरण कन्स्ट्रक्टर" * वह है जिसे मैं ढूंढ रहा था। – abelenky

5

आप सही हैं।

BSTRwchar_t * के लिए टाइपिफ़ है, और CComBSTR/_bstr_t में गैर-कॉन्स रूपांतरण ऑपरेटर wchar_t * पर है।

इस प्रकार, एक अस्थायी _bstr_t आवंटित किया गया है, इसकी शुरुआत के लिए एक सूचक को रूपांतरण ऑपरेटर के माध्यम से someString पर असाइन किया गया है, और ऑब्जेक्ट को जारी किया गया है क्योंकि यह दायरे से बाहर है। फिर आप एक लापरवाही सूचक मिलता है।

आप

_bstr_t someString ("Hello World"); 
बजाय

, या यहाँ तक _bstr_t someString = "Hello, World"; उपयोग कर सकते हैं।

+0

खुशी है कि आप सहमत हैं। मेरा मुद्दा "गुंजाइश" के साथ है। मैं आम तौर पर किसी ऑब्जेक्ट के दायरे को ब्रैकेट-टू-ब्रैकेट मानता हूं; '{' मिलान से '} तक। लेकिन यहां कोई ब्रैकेट नहीं है ... तो अस्थायी '_bstr_t' के" दायरे "को वास्तव में परिभाषित करता है? – abelenky

+2

@abelenky: मैं कोई भाषा वकील नहीं हूं - शायद आप यहां इस सटीक प्रश्न से पूछ सकते हैं, लोगों को जवाब देने में खुशी होगी। मुझे यकीन है कि असाइनमेंट के बाद विनाशक को बुलाया जाता है। 'Const _bstr_t और someString =" हैलो, वर्ल्ड "के विपरीत, जो कॉपी कन्स्ट्रक्टर को कॉल करता है और जिसका दायरा ब्रैकेट द्वारा सीमित किया जाता है। –

+1

@abelenky: प्रासंगिक: http://stackoverflow.com/questions/3041959/life-scope-of- समकालीन- variable –

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