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);

 

2.CComPtr内部对引用类型产生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

 

3.CComPtr内部operator*

operator*

    T& operator*() const
    {
        ATLENSURE(p!=NULL);
        return *p;
    }

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

 

4.CComPtr内部operator T*

operator T*
    operator T*() const throw()
    {
        return p;
    }
    这是个类型转换操作。调用方法如下:
    CComPtr<IUnknown> sp=...
    IUnknown* p=(IUnknown*)sp;

 

5.CComPtr内部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。

6.CComPtr内部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,然后返回接口。如果外部调用需要保存返回的接口,否则就遗失了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值