簡體   English   中英

這個智能指針使用有什么問題?

[英]What is wrong with this Smart Pointer Use?

我最近看到一個關於智能指針的PowerPoint和他們的陷阱,有這個幻燈片(幾乎沒有評論或解釋:

在上下文中:特別是_com_ptr_t ,用於處理AddRef / Release的COM接口的智能指針,由_COM_SMARTPTR_TYPEDEF宏創建。*


錯誤:

 IObjectPtr spObj; for (int i(0); i<MAX; i++) { //passed as actual , no release of previous ptr value spOtherObj->get_Obj(&spObj); } 

下一張幻燈片聲稱如果將spObj放在循環范圍內就可以了:


對:

 for (int i(0); i<MAX; i++) { IObjectPtr spObj; //passed as actual , no release of previous ptr value spOtherObj->get_Obj(&spObj); } 

我研究了這個,但仍然無法弄清楚他們在談論什么。
第一個解決的問題是第二個解決的問題是什么?


我猜測,在更全面的上下文中,正確/錯誤的代碼看起來像:
雖然我的假設可能是錯的

 _COM_SMARTPTR_TYPEDEF(ICalendar, __uuidof(ICalendar)) void get_Calendar(ICalendarPtr* pCalendar) { *pCalendar.CreateInstance(__uuidof(Calendar)); } void WrongMethod(void) { ICalendarPtr spCalendar; for (int i(0); i<MAX; i++) { //passed as actual , no release of previous ptr value get_Calendar(&spCalendar); } } 

這很可能是指ATL::CComPtr而不是_com_ptr_t

問題是CComPtr::operator&返回包裝指針的地址但不釋放它,因此假設被包裝的接口不是NULL,如果它被聲明出循環,則泄漏對象。

實現確認了這一事實,這是直接從ATL標題復制的,包括注釋:

//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;
}

_com_ptr_t修復了這個問題,並且一般使用起來更方便,因此應該首選適用。

這些是ATL :: CComPtr智能指針(它們非常聰明,順便說一句)。

operator &該對象類型返回其中的原始接口指針的地址。 因此,第一個循環實際上並不比這樣做更好:

IObject* pObj = NULL;
for (int i(0); i<MAX; i++)
{
    spOtherObj->get_Obj(&pObj);
}

每次迭代,都不會釋放先前迭代的接口。 它只是丟失,泄露,底層coclass的引用計數將被人為地鎖定。

通過將智能指針移動到循環內部 ,您現在允許智能指針對象的析構函數在下一次迭代之前清理獲取的每個接口,kick ->Release() 擴展的代碼實際上是這樣的:

for (int i(0); i<MAX; i++)
{
    IObject* pObj = NULL;
    spOtherObj->get_Obj(&pObj);
    if (pObj) pObj->Release();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM