2012-06-19 37 views
2

我有一個ATL COM組件方法,它將BSTR作爲參數。我需要將每個調用添加到數組中的此方法。我不能使用SAFEARRAY,因爲這是固定的大小,所以我認爲std :: vector將是最簡單的選擇。當然,我將需要爲向量的每個添加調用SysAllocString。這意味着在向量被銷燬之前需要爲每個條目調用SysFreeString。將BSTR存儲在std :: vector中?

我正在尋找一個更簡單/更清潔的解決方案,並且想到將向量聲明爲包含自動清理的向量< _bstr_t>。然而,我腦海中的某些東西正在引發警報,將標準容器中的有效指針作爲一個有效指標。我的擔憂是否合理?還是我可以安全地做到這一點?如果沒有其他更好的解決方案?

回答

3

[關於vector<_bstr_t>]是我的擔憂有道理或我可以放心地做到這一點?

是的。雖然你可以安全使用_bstr_t請記住,它不僅是一個智能指針,但它是一個引用計數智能指針。這意味着額外的成本。

如果沒有其他更好的解決方案?

我通常會用一個CComBSTR代替BSTR_bstr_t。如果你需要參考計數,那麼你必須回落_bstr_t。例如:如果你也使用ATL,你可能只想要CComBSTR

CComBSTR類是BSTRs的包裝,它是以長度爲前綴的字符串。長度作爲整數存儲在字符串中的數據之前的內存位置。

BSTR在最後一個計數字符之後以空字符終止,但也可能包含嵌入字符串中的空字符。字符串長度由字符數決定,而不是第一個空字符。

所以,在做出選擇之前,請務必考慮以下幾點:

  1. _bstr_t超過BSTRCComBSTR提供任何引用計數引用計數智能指針包裝。
  2. _bstr_t不是重新定義了操作符地址,因此可以安全地存儲在STL容器中。有了CComBSTR,您將需要使用CAdapt

關於CAdapt對象:

CAdapt是用來包裹的是重新定義地址的運營商(運營商&)返回比對象的地址以外的其他類的簡單的模板。此類的示例包括ATL的CComBSTR,CComPtr和CComQIPtr類,以及編譯器COM支持類_com_ptr_t。這些類都重新定義了address-of運算符,以返回其數據成員之一的地址(在CComBSTR中爲BSTR,而在其他類中爲接口指針)。

然後你可以使用:

typedef std::vector< CAdapt<CComBSTR> > MyString; 
1

我想你可以安全地做到這一點。唯一禁止的是使用auto_ptr的容器。

+0

不過,這不只是_bstr_t一種類型的智能指針?或者它是否特別說明你不應該把auto_ptr放進去?如果是這樣,爲什麼這是特別你不應該把auto_ptr在那裏?我曾經在某個時候讀過這篇文章,但我不記得現在爲什麼。 – Jonnster

+1

auto_ptr具有「怪異」的複製語義,但std容器需要一些標準的複製和分配語義。引用計數智能指針通常具有這樣的語義。 – ltjax

+0

aalways喜歡unique_ptr到shared_ptr –

1

由於_bstr_t不會使運算符&超載,因此在stl容器中使用它沒有任何問題。

0

BSTR是一個C結構,你必須調用SysAllocStringSysFreeString_bstr_t是C++類型,可爲您調用SysAllocStringSysFreeString,並且在std::vector中完全安全。在處理_bstr_t對象時,您不必也不應該撥打電話SysAllocStringSysFreeString

如果您是不是與C結構處理BSTR對象:
(1)您可以放心地智能指針,儲存在容器中,除了auto_ptr,它只是假裝聰明。
(2)A vector可以存儲_bstr_t,但它不瞭解SysFreeString,您將不得不手動調用它。就像你必須在原始指針上使用delete一樣,因爲_bstr_t而不是一個智能指針。
(3)a std::unique_ptr<BSTR, HRESULT (*)(BSTR)>(mybstr, SysFreeAlloc)是一款智能指針,它可以安全且神奇地爲您做所有事情,包括完全安全地存儲在一個向量中,無需開銷。然而,這是醜陋的來寫,所以多數人使用:

template<class T, class F> 
std::unique_ptr<T, F> make_unique(T t, F f) 
{return std::unique_ptr<T,F>(std::move(t), std::move(f));} 

typedef decltype(make_unique(declval<BSTR>(), SysFreeAlloc)) bstr_ptr; 
std::vector<bstr_ptr> container; 
container.push_back(make_unique(mybstr, SysFreeAlloc)); 
+0

@Jonnster:編輯我的答案,我現在意識到'_bstr_t'和'BSTR'>之間的區別。< –

相關問題