ATL CComPtr附加,分离和析构函数

时间:2014-11-01 08:44:42

标签: c++ visual-c++ com atl

我想...... Attach和Detach不会改变引用计数。 但是CComPtr的析构函数会调用它包含的指针。

每次使用附件时,是否有必要调用分离?...

{
    CComPtr<IObj> pPtr;
    pPtr.Attach(pPtr1);
    .....//No detach on pPtr

}

2 个答案:

答案 0 :(得分:3)

正如您所提到的,Attach / Detach不会影响参考计数器的设计。因此,当您特别需要跳过添加引用时,您将使用它们。否则,您以更自然的方式初始化指针(构造函数,赋值运算符等)。

您对Attach的特殊需求通常是为了补偿已添加的外部参考。这样你的CComPtr析构函数就会在到时的时候正确释放它。

所以,不,您不必将AttachDetach配对。如果必须,你可能不会在第一时间使用Attach。

例如,Attach

{
  // We have an oustanding reference on pRawFoo we want to safely compensate for
  CComPtr pFoo;
  pFoo.Attach(pRawFoo); // No effect on counter, but since here we would release 
                        // the reference going out of scope
  // ...
} // ~CComPtr releases the reference as intended

不需要Attach

{
  // External pRawFoo is in proper balance in terms of reference count
  CComPtr pFoo;
  pFoo = pRawFoo; // No need in Attach, pFoo adds a reference
  // ...
} // ~CComPtr releases the reference as intended

答案 1 :(得分:1)

与大多数智能指针一样,CComPtr<T>表示所有权并使用RAII语义来确保正确清理所拥有的资源。方法AttachDetach用于转移所有权,部分原因是参考计数簿记可能相对昂贵。因此,您需要在上下文中回答的问题是所有权模式是什么。

在两个CComPtr<T>个对象之间转移所有权时,会有匹配AttachDetach来电的倾向,但它们会出现在单独的对象上:

    spFoo2.Attach(spFoo1.Detach());

考虑以下代码段以及它们对IFoo对象的所有权的指示。 m_spFoospFoo都是CComPtr<IFoo>值:

HRESULT C::GetFoo_1(IFoo **ppFoo)
{
    return m_spFoo.QueryInterface(ppFoo); // or m_spFoo.CopyTo(ppFoo)
}
HRESULT C::GetFoo_2(IFoo **ppFoo)
{
    *ppFoo = m_spFoo.Detach();
    return S_OK;
}
    spFoo = obj.GetFoo_3();
    spFoo.Attach(obj.GetFoo_4());

这是我对这些片段的看法。

  • 第一种是将IFoo返回给调用者的常用方法,遵循通常的语义,其中调用者接收带有递增引用计数的副本。
  • 如果所有权传递给来电者,第二个是可以的;调用者获取C对象以前具有的副本。
  • 第三个可能已经返回CComPtr<IFoo>CComPtr<IFoo>&(非参考案例可能导致额外的参考计数簿记),我们正在指示进一步的共享所有权;也就是说,我们希望将其保留的时间超过该声明。
  • 第四个表示GetFoo_4中的异常语义,因为它必须提供我们不想进一步增加的原始IFoo*的引用计数。