DirectX,引用计数和智能指针

时间:2015-01-25 23:17:21

标签: c++ windows-7-x64 smart-pointers directx-11

我正在用C ++构建一个游戏,为了保护自己免受内存泄漏的影响,我想确保从一开始就做好一切。

目前,我有一个包含所有direct3D内容的D3D课程。

但是,我的Render()方法需要在某个时候访问DeviceContext。为此,我的D3D类必须从其自身返回ID3D11DeviceContext指针。这意味着我有另一个对该COM对象的引用而没有增加它的引用计数。

例如:

Render()
{
    m_d3d.GetDevCon()->DoWhatever();
}

我可以这样使用它,这意味着我永远不必制作指针的外部副本吗?这样安全吗?我能做些什么来保护我的程序免受不良事件的影响,例如潜在的:

Render()
{
    ID3D11DeviceContext* devCon = m_d3d.GetDevCon();
    devCon->DoWhatever();
}

我可以看到这意味着引用计数与实际参考数量不匹配。

基本上我想尝试避免使用原始指针,如果可以的话。我想要不仅仅使用智能指针,而且知道什么时候使用智能指针。

1 个答案:

答案 0 :(得分:2)

对于像Direct3D对象这样的COM对象,您应该使用smartpointer Microsoft::WRL::ComPtr(可在所有C ++应用程序中使用Windows 8.x SDK,包括Win32桌面应用程序)。

std::unique_ptr对于许多用途都很有用,就像std::shared_ptr一样,但它们对COM对象的效果不佳。

只要您没有另一个可能释放ID3D11DeviceContext足以解除分配的线程,下面的代码使用原始指针而不增加引用计数是“安全的”。这将是一个奇怪的程序,它将从你正在运行渲染的线程之外的线程中执行此操作。

Render()
{
    ID3D11DeviceContext* devCon = m_d3d.GetDevCon();
    devCon->DoWhatever();
}

换句话说,在更新/渲染/呈现的标准游戏循环中,您不需要创建“强引用”(即增加引用计数)只是为了使用它进行渲染,您可以安全地使用'弱引用'(即指针不增加引用计数),只要你有一个明确的初始化过程,即只能在该游戏循环的特定点销毁和/或重新创建设备/上下文(即不在更新或渲染,但可能是对失败的礼物的回应。)

有关详细信息,请参阅Smart Pointers (Modern C++)Direct3D Win32 Game Visual Studio template

您可以在this文章中找到智能指针的各种“异常安全”用法示例。