C++ DirectX COM对象在这种情况下内存泄漏?

C++ DirectX COM对象在这种情况下内存泄漏?,c++,memory,directx,direct3d,C++,Memory,Directx,Direct3d,如果我有这样一个类或结构: 布尔局部范围函数 { 布尔结果; IDXGIFactory*PFFactory; IDXGIAdapter*pAdapter; result=//在这里对对象执行一些操作 如果!结果返回false; result=//在这里对对象执行一些操作 如果!结果返回false; result=//在这里对对象执行一些操作 如果!结果返回false; //等等。。。。。。 //___在这里打扫卫生___// pFactory->Release;pFactory=nullptr

如果我有这样一个类或结构:

布尔局部范围函数 { 布尔结果; IDXGIFactory*PFFactory; IDXGIAdapter*pAdapter; result=//在这里对对象执行一些操作 如果!结果返回false; result=//在这里对对象执行一些操作 如果!结果返回false; result=//在这里对对象执行一些操作 如果!结果返回false; //等等。。。。。。 //___在这里打扫卫生___// pFactory->Release;pFactory=nullptr; pAdapter->Release;pAdapter=nullptr; 返回true;//如果全部通过
} 是的,它会泄漏,因为你跳过了清理。COM对象使用引用计数,交易是计数必须准确,系统才能在正确的时间删除内存

这里的解决方案实际上非常简单:使用Microsoft::WRL::ComPtr。这个智能指针负责在需要时调用Release,无论您如何离开范围

另一件需要注意的事情是COM对象不会将错误作为bool返回。他们是我们的领袖。您不应该忽略它们,因为如果函数返回HRESULT,它可能会失败。您也不应该使用==S_OK之类的。您应该使用失败的宏、成功的宏或类似的东西


有关使用ComPtr的更多信息,请参阅。

谢谢Chuck。到目前为止,我只使用了原始指针,但是ComPtr和unique_指针对于这类事情似乎非常方便。ComPtr是否与唯一_指针或共享_指针有更多相似之处?另外,我一直在试图找出两个COM对象方法.get和.getAddressOf之间的区别。我无法从MSDN中理解它在说什么,因为我觉得它的措辞相当。我应该传递.get还是getAddressOf作为参数?Thank.ComPtr是一个引用计数的共享智能指针,因此在逻辑上类似于shared_ptr。有关ComPtr的使用提示,请参阅,我在其中专门讨论了为什么会将Get和GetAddressOf与Direct3D参数一起使用。谢谢,我已经读了大约3遍了。它正在慢慢下沉。不同之处在于get是指针,getAddressOf是指针的地址,您可以将其传递给使用指针到指针参数的函数。如果你不介意解释的话,还有一件事。通常,如果您创建一个指向某个对象的指针,您可能会立即检查它是否为null,这表示失败。所以当我去的时候,如果!ptr返回false,是否需要将其更改为“如果”!ptr.get返回false?作为唯一的ptr,它不是指针本身,而是一个指针的包装器。智能指针有一个运算符bool,正好用于该模式。也就是说,在COM的情况下,通常检查工厂函数的HRESULT,而不是检查返回指针中的null。
#include <wrl/client.h>

using Microsoft::WRL::ComPtr;

bool localScopeFunc()
{
    ComPtr<IDXGIFactory> pFactory;
    ComPtr<IDXGIAdapter> pAdapter; 

    HRESULT result = //Do something here with the objects
    if (FAILED(result)) return false;

    result = //Do something here with the objects
    if (FAILED(result)) return false;

    result = //Do something here with the objects
    if (FAILED(result)) return false;

    // And so on......

    return true; // If all passes
}