我正在用C ++构建一个游戏,为了保护自己免受内存泄漏的影响,我想确保从一开始就做好一切。
目前,我有一个包含所有direct3D内容的D3D课程。
但是,我的Render()方法需要在某个时候访问DeviceContext。为此,我的D3D类必须从其自身返回ID3D11DeviceContext指针。这意味着我有另一个对该COM对象的引用而没有增加它的引用计数。
例如:
Render()
{
m_d3d.GetDevCon()->DoWhatever();
}
我可以这样使用它,这意味着我永远不必制作指针的外部副本吗?这样安全吗?我能做些什么来保护我的程序免受不良事件的影响,例如潜在的:
Render()
{
ID3D11DeviceContext* devCon = m_d3d.GetDevCon();
devCon->DoWhatever();
}
我可以看到这意味着引用计数与实际参考数量不匹配。
基本上我想尝试避免使用原始指针,如果可以的话。我想要不仅仅使用智能指针,而且知道什么时候使用智能指针。
答案 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文章中找到智能指针的各种“异常安全”用法示例。