CComPtr<T>是一個ATL中的一個智能指針類型,它及它的派生類CComQIPtr<T>為我們提供了智能管理COM接口指針的能力。 也就是在析構時自動釋放資源的工具類,這些工具類能有效地幫助我們杜絕內存泄漏、句柄沒有釋放之類錯誤。她們是很智能、很聰明,不過這要我們寫出正確的程式,如果使用不正確也會出現上述這些問題。往往內存泄漏、句柄沒有釋放這些錯誤很難一下調試出來,多數是通過工具來檢查出來。有的工具對智能指針的誤用也是較難發現。
下面是我經歷過的一個場景:
[
object,
uuid(….),
….
]
Interface IA
{
…
};
//Client;
Class B
{
IA GetIA(..);
};
B b;
CComPtr<IA> aPtr(b.GetIA(…));
這樣導致我的一個結構化存儲資源被長久地占用,不能刪除。有人或許已經知道問題的所在了。這個錯誤就在于CComPtr<IA> aPtr(b.GetIA(…));這樣從方法傳出來的接口就沒有能夠調用Release,這樣泄漏就產生了。正確的使用應如下
CComPtr<IA> aPtr;
aPtr.Attach(b.GetIA(…));
拿出這兩個方法的源代碼就非常清楚了。
CComPtrBase(_In_opt_ T* lp) throw()
{
p = lp;
if (p != NULL)
p->AddRef();
}
void Attach(_In_opt_ T* p2) throw()
{
if (p)
p->Release();
p = p2;
}
對于Detach和析構方法不會因混亂造成問題,因為Detach總是用于一個方法中要返回一個智能指針的實際接口時調用從而達到使代碼簡潔。而析構也會因為分離出了接口指針而不做任何事情。