700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > CComPtr对象作为参数进行 1.值传递 2.引用传递 3.做为返回值的注意事项

CComPtr对象作为参数进行 1.值传递 2.引用传递 3.做为返回值的注意事项

时间:2019-08-17 21:45:04

相关推荐

CComPtr对象作为参数进行 1.值传递 2.引用传递 3.做为返回值的注意事项

1.导致内存泄露的一种调用方式:

下面方法是错误的:

IA *pA=NULL;

p->QueryInterfaces(...,&pA);//从某个已有接口查询获取IA

CComPtr<IA> spA(pA)

QueryInterface方法会导致pA->AddRef被调用一次,CComPtr<IA>构造函数又会调用一次AddRef,而最后spA析构时只调用了一次Release,因此COM对象没有被销毁,内存泄露了。

正确做法如下:

IA *pA=NULL;

p->QueryInterfaces(...,&pA);

CComPtr<IA> spA;

spA.Attach(pA);

或者

CComPtr<IA> spA(pA)

p->QueryInterfaces(...,&pA.p);

omPtr内部对引用类型产生Assert原因

不能使用的operator&

//The assert on operator& usually indicates a bug. If this is really

//what is needed, however, take the address of the p member explicitly.

T** operator&() throw()

{

ATLASSERT(p==NULL);

return &p;

}

当你的CComPtr的p成员变量(集成而来的)不为NULL时,debug模式下会弹出错误对话框。看看上面的注释,这个函数被设计用来防止对智能指针直接调用取地址操作符的。实在要用,请用这种方法:&sp.p

omPtr内部operator*

operator*

T& operator*() const

{

ATLENSURE(p!=NULL);

return *p;

}

有了这个操作,我们就可以使得CComPtr拥有和普通指针同样的行为,通过*p来获得p所指对象的引用。

omPtr内部operator T*

operator T*

operator T*() const throw()

{

return p;

}

这是个类型转换操作。调用方法如下:

CComPtr<IUnknown> sp=...

IUnknown* p=(IUnknown*)sp;

omPtr内部CopyTo

CopyTo

_Check_return_ HRESULT CopyTo(_Deref_out_opt_ T** ppT) throw()

{

ATLASSERT(ppT != NULL);

if (ppT == NULL)

return E_POINTER;

*ppT = p;

if (p)

p->AddRef();

return S_OK;

}

将自己的接口拷贝个参数指针,并调用AddRef。

omPtr内部Attach和Detach方法

void Attach(_In_opt_ T* p2) throw()

{

if (p)

p->Release();

p = p2;

}

// Detach the interface (does not Release)

T* Detach() throw()

{

T* pt = p;

p = NULL;

return pt;

}

Attach方法先释放原先p所指接口,然后接受新接口,注意,不会导致AddRef调用。

Detach方法将p设置为NULLL,然后返回接口。如果外部调用需要保存返回的接口,否则就遗失了。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。