我想...... Attach和Detach不会改变引用计数。 但是CComPtr的析构函数会调用它包含的指针。
每次使用附件时,是否有必要调用分离?...
{
CComPtr<IObj> pPtr;
pPtr.Attach(pPtr1);
.....//No detach on pPtr
}
答案 0 :(得分:3)
正如您所提到的,Attach
/ Detach
不会影响参考计数器的设计。因此,当您特别需要跳过添加引用时,您将使用它们。否则,您以更自然的方式初始化指针(构造函数,赋值运算符等)。
您对Attach
的特殊需求通常是为了补偿已添加的外部参考。这样你的CComPtr
析构函数就会在到时的时候正确释放它。
所以,不,您不必将Attach
与Detach
配对。如果必须,你可能不会在第一时间使用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语义来确保正确清理所拥有的资源。方法Attach
和Detach
用于转移所有权,部分原因是参考计数簿记可能相对昂贵。因此,您需要在上下文中回答的问题是所有权模式是什么。
在两个CComPtr<T>
个对象之间转移所有权时,会有匹配Attach
和Detach
来电的倾向,但它们会出现在单独的对象上:
spFoo2.Attach(spFoo1.Detach());
考虑以下代码段以及它们对IFoo
对象的所有权的指示。 m_spFoo
和spFoo
都是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*
的引用计数。