QueryInterface()成功时是否可以提供nullptr ?
Could QueryInterface() provide us with nullptr when succeed?
想象一个场景:
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()
需要在成功和失败时提供一个有效的(因此非空)接口指针。但是,您不知道某些特定的实现是否遵循该规则,并且您引用的代码很可能试图进行防御。
也就是说,下面的
HRESULT hr = CoCreateInstance(CLSID_FilterGraph, NULL,
CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pGraph));
还在底层调用QueryInterface()
来检索指向所请求接口的指针。如果代码想要防御,它也应该检查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()
,其工作原理如上所述,refcount现在是2,然后您Release()
对象一次,它泄漏。结果到底有多糟取决于很多因素。
与CoCreateInstance()
相同-它在引擎盖下调用相同的QueryInterface()
。两者都可能被破坏,并且无论是否检查检索到的指针是否为null,您的里程都可能发生变化。
相关文章:
- C++默认情况下,指针类型数组的元素是否保证初始化为 nullptr?
- 在 nullptr 上调用无状态类的非静态成员函数是否合法?
- 检查类方法中是否(此 == nullptr)
- 检查nullptr是否100%保护内存布局不受segfault影响
- 是否强制转换void**并将第一个字节设置为nullptr
- 检查C++中是否只有一个字符串变量不是 nullptr
- 空向量占用的空间是否与指向当前设置为 nullptr 的类型的指针一样多
- 如何使用断言来检查weak_ptr是否为 nullptr
- 在shared_ptr的自定义删除器中检查 nullptr 是否有意义?
- c++是否需要在用户定义和类特定的删除运算符中处理nullptr
- 一旦 std::weak_ptr 上的锁返回了 nullptr,它是否还会再次成为非 null
- std::unique_ptr 是否在其析构函数中将其基础指针设置为 nullptr?
- 我可以得到指向 nullptr 的指针的指针吗,它是否有效
- Qt 是否可以安排在 QObject 被销毁时将 QObject* 设置为 nullptr
- 当调用析构函数时,是否可以将指向类实例的指针设置为nullptr
- 编译器是否假定"this"在调试模式下不是 nullptr?
- 取消引用等于 nullptr 的指针是否是标准的未定义行为?
- 在C++ - 是否可以将易失性shared_ptr与 nullptr 进行比较
- nullptr是否释放指针的内存
- 将指针设置为 nullptr 是否会影响指向同一地址的其他指针