Aru*_*oor 11 c++ com interface object queryinterface
为什么QueryInterface()呼叫总是跟着Release()呼叫?例如,我看过MSDN的示例代码如下:
HRESULT hr = S_OK;
CDecoder *pObj = new CDecoder(&hr);
if (SUCCEEDED(hr))
{
*ppv = NULL;
hr = pObj->QueryInterface(riid, ppv);
}
pObj->Release();
return hr;
Run Code Online (Sandbox Code Playgroud)
有人可以解释Release()这里打电话的意图吗?
Jer*_*fin 15
它并不总是像这样直接跟随,尽管这很常见.
COM对象是引用计数.最初创建对象时,会得到指向的对象IUnknown.然后你获得一些其他的接口QueryInterface.由于您(通常)不再关心IUnknown界面,因此您将释放该界面.当您释放您获得的其他接口时,引用计数将为0,因此可以销毁该对象.IUnknown但是,如果不释放,则引用计数将保持非零,因此无法销毁对象.
您不会立即释放的最明显的情况IUnknown是何时/如果您需要获得多个其他接口.在这种情况下,你会IUnknown在释放之前得到第二个和第三个接口IUnknown.至少有可能在您创建对象之后可能不知道第三个(或后续)接口的情况,因此您可能需要IUnknown在释放之前保留对该任意长度的访问权限.
为什么QueryInterface调用总是跟随Release调用?
因为QueryInterface将调用AddRef,这会增加指针的引用计数.当对指针有0个引用时,它将被释放.
注意:这个问题的答案QueryInterface实际上有些混乱.它只是检索指向对象上支持的接口的指针,并增加该对象的引用计数.它不会为它实现的每个接口创建新对象.
例如,如果您有一个实现2个接口的对象,那么该调用将简单地将该对象强制转换为每个接口,并递增一个用作引用计数的变量.
注意:引用计数可以以不同的方式实现,但上面解释了通常的方案.特别是@Ben描述了一个撕下接口,下面强调了在返回给你的接口指针上调用Release的重要性.