2014-07-03 65 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類型,所以它具有構造/拆解/操作等等。

BSTR是一種typedef只是WCHAR*,所以它沒有任何邏輯。它只是一個愚蠢的指針。

回答

3

中的代碼問題

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

正在做一個conversion constructor call它可以創建通過wchar_t[]一個bstr_t實例。這本身就很好。例如,如果你想調用一個函數接受BSTR並傳遞一個字符串在那裏,你可以很容易地做到這一點:

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

,這將是可以的,因爲臨時將生存直到整個語句結束它結束於分號所在的位置(這就是C++臨時對象的工作方式)。

但是所討論的代碼是不行的,因爲_bstr_t實例隨後被用於實例化一個BSTR實例,它比臨時(臨時設置在分號和BSTR破壞居住更長(在bstr_t類使用轉換運算符)指針someString的生活遠遠超出了這一點)。所以你得到一個懸掛BSTR指針someString使用它導致未定義的行爲。如果OLE堆選擇保留用於映射到進程地址空間的字符串的內存,它甚至可能會工作。

class _bstr_t與實現(在Windows SDK文件comutil.h)提供的,所以你可以進入你的調試器的代碼,並看到有當臨時創建一個SysAllocString()呼叫,然後一個SysFreeString()呼叫時被銷燬而後者在代碼進入下一行之前發生。因此,在代碼進入下一行之前,OLE堆中的字符串對象會被釋放,並且指針在相關代碼之後立即懸空。我想這足以說服即使是最懷疑的人。

所以是的,你是對的,代碼是錯誤的。正確的代碼是:

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

謝謝,術語*「轉換構造函數」*是我正在尋找。 – abelenky

5

你說得對。

A BSTRwchar_t *的typedef,並且CComBSTR/_bstr_t具有非const轉換運算符到wchar_t *

因此,分配了一個臨時的_bstr_t,通過轉換運算符將一個指向其開始的指針指定給someString,並且在超出範圍時釋放該對象。然後你得到一個懸掛指針。

您可以使用

_bstr_t someString ("Hello World"); 

代替,甚至_bstr_t someString = "Hello, World";

+0

很高興你同意。我的問題是「範圍」。我通常認爲一個對象的範圍是括號到括號;從'{'直到匹配的'}'。但是這裏沒有括號......那麼究竟是什麼定義了臨時的'_bstr_t'的「範圍」? – abelenky

+1

@abelenky:相關:http://stackoverflow.com/questions/3041959/life-scope-of-temporary-variable –

相關問題