我常写以下代码:IMyInterface* pi;
HRESULT hr = MyObject->QueryInterface(IID_IMyInterface, (void**)&pi);//MyObject是有效对象...use pi........
.....
......pi->Release();
通常情况下“pi->Release();”的执行不会引起MyObject的析构,但有时候会,谁能告诉我怎么判断在QueryInterface()后面是否要调用Release();“每个QueryInterface()后面总要调用Release()”到底对不对呢?
HRESULT hr = MyObject->QueryInterface(IID_IMyInterface, (void**)&pi);//MyObject是有效对象...use pi........
.....
......pi->Release();
通常情况下“pi->Release();”的执行不会引起MyObject的析构,但有时候会,谁能告诉我怎么判断在QueryInterface()后面是否要调用Release();“每个QueryInterface()后面总要调用Release()”到底对不对呢?
--MSDN
QueryInterface()函数内没有调用AddRef(),所以除非你能保证在当前作用域内该对象不会被释放,否则就一定要调用AddRef(),如果调用了AddRef(),也就应当在使用完后调用Release()
下面是ATL头文件AtlBase.h中AtlInternalQueryInterface函数的实现
ATLINLINE ATLAPI AtlInternalQueryInterface(void* pThis,
const _ATL_INTMAP_ENTRY* pEntries, REFIID iid, void** ppvObject)
{
ATLASSERT(pThis != NULL);
// First entry in the com map should be a simple map entry
ATLASSERT(pEntries->pFunc == _ATL_SIMPLEMAPENTRY);
if (ppvObject == NULL)
return E_POINTER;
*ppvObject = NULL;
if (InlineIsEqualUnknown(iid)) // use first interface
{
IUnknown* pUnk = (IUnknown*)((int)pThis+pEntries->dw);
pUnk->AddRef();
*ppvObject = pUnk;
return S_OK;
}
while (pEntries->pFunc != NULL)
{
BOOL bBlind = (pEntries->piid == NULL);
if (bBlind || InlineIsEqualGUID(*(pEntries->piid), iid))
{
if (pEntries->pFunc == _ATL_SIMPLEMAPENTRY) //offset
{
ATLASSERT(!bBlind);
IUnknown* pUnk = (IUnknown*)((int)pThis+pEntries->dw);
pUnk->AddRef();
*ppvObject = pUnk;
return S_OK;
}
else //actual function call
{
HRESULT hRes = pEntries->pFunc(pThis,
iid, ppvObject, pEntries->dw);
if (hRes == S_OK || (!bBlind && FAILED(hRes)))
return hRes;
}
}
pEntries++;
}
return E_NOINTERFACE;
}可以看到在返回接口指针之前已经调用过AddRef,因此自己是不用再调了的
class CMyClass :
public ISupportErrorInfo,
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CMyClass,&CLSID_MyClass>,
public IDispatchImpl<IMyInterface, &IID_IMyInterface, &LIBID_MyLib>
{
...
}
在程序中如下使用:
CComObject<CMyClass> *m_pObj;//成员变量CComObject<CMyClass>::CreateInstance(&m_pObj);//创建
IMyInterface* t=NULL;
m_pObj->QueryInterface(IID_IMyInterface, (void**)&t);
....//使用
t->Release();会导致m_pObj析构。注:使用过程中只是调用了接口的方法如果ATL中的QueryInterface()自动调用AddRef(),为什么我会得到以上结果?