This question already has answers here:
Handling CoCreateInstance return value
(2个答案)
6年前关闭。
想象一个情况:
我想知道
我认为那部分
还可以在后台调用
这里的问题是当您获得
很好,防御代码将避免将在此处检索到的空指针与返回的
与
(2个答案)
6年前关闭。
想象一个情况:
CComPtr<IGraphBuilder> pGraph;
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pGraph));
if (SUCCEEDED(hr))
{
CComPtr<IMediaControl> pControl;
hr = pGraph->QueryInterface(IID_PPV_ARGS(&pControl));
if(SUCCEEDED(hr))
{...}
}
我想知道
pControl
在最后一个块{...}
中是否可以为nullptr。发生问题了,因为我看到了以下代码:if(SUCCEEDED(hr) && pControl)
{...}
我认为那部分
&& pControl
是多余的。我对吗? 最佳答案
QueryInterface()
是必需的,以便在成功时提供有效的(所以非null)接口(interface)指针,而在失败时提供null指针。但是,您不知道是否有某些特定的实现遵循该规则,您引用的代码很可能会起到防御作用。
也就是说,以下
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pGraph));
还可以在后台调用
QueryInterface()
来检索指向所请求接口(interface)的指针。如果代码想要防御,也应该在成功时检查pGraph
是否为非空。这里的问题是当您获得
S_OK
和空指针时,您不知道它有多糟。假设QueryInterface()
的工作方式如下(的代码确实很糟糕,不适用于的任何地方):HRESULT TheClass::QueryInterface( REFIID iid, void** ppv )
{
if( iid == SomeSpecificIID ) {
AddRef();
*ppv = 0; //BAD IDEA, BAD CODE, JUST DON'T
return S_OK;
} else {
//whatever
}
}
很好,防御代码将避免将在此处检索到的空指针与返回的
S_OK
一起取消引用,但引用计数将不正确-没有人将有机会调用匹配的Release()
。因此,您实例化了这样一个对象,然后调用QueryInterface()
,它的工作原理与上面相同,引用计数现在为2,然后对对象进行Release()
一次,然后泄漏。结果有多糟糕取决于许多因素。与
CoCreateInstance()
相同-在后台调用相同的QueryInterface()
。无论是否检查检索到的指针是否为null,两者都可能损坏,并且里程可能会有所不同。关于c++ - 成功时,QueryInterface()可以为我们提供nullptr吗? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25325891/
10-09 06:01