2014-11-01 26 views
0

我認爲.. 連接和分離不會引用計數發生變化。 但是CComPtr的析構函數釋放了它所包含的指針。ATL CComPtr連接,分離和分解

因此,它是需要調用分離每當一個使用附加?...

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

}

回答

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

最喜歡的智能指針,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(); 

這裏是我的就這些片段。

  • 首先是一個IFoo返回到調用者,以下的通常語義其中所述呼叫者接收具有遞增的參考計數的副本的非常通常的方式。
  • 如果所有權被傳遞給調用者,第二個就可以了;來電者獲取C對象以前擁有的副本。
  • 第三個可能已經返回CComPtr<IFoo>CComPtr<IFoo>&(非參考案例可能會導致額外的引用計數記帳),我們正在指示進一步的共享所有權;也就是說,我們希望保持它比這個陳述更長的時間。
  • 第四位表示GetFoo_4中的異常語義,因爲它必須在原始IFoo*上提供我們不想進一步增加的引用計數。