天天看點

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報警)

以剛才的程式為例:

ccomptr<ihello> pcopy = phello;

由于pcopy是一個局部的對象,是以即使otherapp()抛出異常,pcopy也會被析構,指針能夠被釋放。

如果不想在程式臨近釋出前,還因為com指針的引用計數造成崩潰的話,就牢記這一點吧:程式中除了參數之外,不要直接使用com指針類型,一定要全部以ccomptr<ixxx>代替。