CComPtr用法
COM接口指針很危險,因為使用過程中需要每一個使用者都要嚴格並且正確的AddRef和Release,一旦出現問題,就會造成對象不能被正常釋放,或者對象被重複刪除,造成程序崩潰。所以使用COM接口,必須小心翼翼才行。
但是,即使所有的代碼中,都正確的AddRef和Release,也不一定能保證萬無一失,例如:
void SomeApp( IHello * pHello )
{
IHello* pCopy = pHello;
pCopy->AddRef();
OtherApp();
pCopy->Hello();
pCopy->Release();
}
看起來好像無懈可擊,但是假設OtherApp中拋出了異常,那麼pCopy->Release不就被跳過去了嗎?
幸好,所有的問題都從簡單到複雜,再從複雜到簡單的,因為我們有CComPtr!
CComPtr被稱為智能指針,是ATL提供的一個模版類,能夠從語法上自動完成AddRef和Release。(源代碼在atlbase.h中)
CComPtr的用法很簡單,以IHello*為例,將程序中所有接口指針類型(除了參數),都使用CComPtr<IHello> 代替即可。即程序中除了參數之外,再也不要使用IHello*,全部以CComPtr<IHello>代替。
CComPtr的用法和普通COM指針幾乎一樣,另外使用中有以下幾點需要注意。
1. CComPtr已經保證了AddRef和Release的正確調用,所以不需要,也不能夠再調用AddRef和Release。
2. 如果要釋放一個智能指針,直接給它賦NULL值即可。(這一點要牢記曾因為沒有設置為null而出錯)
3. CComPtr本身析構的時候會釋放COM指針。
4. 當對CComPtr使用&運算符(取指針地址)的時候,要確保CComPtr為NUL。(因為通過CComPtr的地址對CComPtr賦值時,不會自動調用AddRef,若不為NULL,則前麵的指針不能釋放,CComPtr會使用assert報警)
以剛才的程序為例:
void SomeApp( IHello * pHello )
{
CComPtr<IHello> pCopy = pHello;
OtherApp();
pCopy->Hello();
}
由於pCopy是一個局部的對象,所以即使OtherApp()拋出異常,pCopy也會被析構,指針能夠被釋放。
如果不想在程序臨近發布前,還因為COM指針的引用計數造成崩潰的話,就牢記這一點吧:程序中除了參數之外,不要直接使用COM指針類型,一定要全部以CComPtr<IXXX>代替。
最後更新:2017-04-03 15:22:09