我最近看到了一张关于智能指针及其陷阱的 PowerPoint,其中有这张幻灯片(几乎没有评论或解释:
在上下文中:特别是 _com_ptr_t , 用于处理 AddRef/Release 的 COM 接口(interface)的智能指针,由 _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&
返回包装指针的地址但不释放它,因此如果它被声明在循环外就会泄漏对象,假设包装接口(interface)不为空。
实现承认这个事实,这是直接从 ATL header 复制的,包括注释:
//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
修复了这个问题,一般使用起来更方便,所以应该首选。
关于c++ - 这个智能指针使用有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20011114/