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总是用于一个方法中要返回一个智能指针的实际接口时调用从而达到使代码简洁。而析构也会因为分离出了接口指针而不做任何事情。