我正在使用智能指针或ComPtr。我正在使用它与我的directX应用程序,我还没有看到其他人使用ComPtr在其代码中调用release函数。那么智能指针会释放智能指针所指的数据,还是需要手动执行?我不知道这是否能让你知道,如果不这样做,我会以更好的细节作出回应。我是否必须使用ComPtr调用释放函数?
回答
您不应该在ComPtr
上拨打AddRef
或Release
,并且默认情况下您不能。你必须使用像comPtr.Get()->Release
这样的hacky模式来做到这一点,而且你最喜欢会导致问题。
Microsoft::WRL::ComPtr
的目的是在正常代码和处理C++异常时自动清除COM指针。将ComPtr的副本复制到另一个ComPtr会自动增加ref-count,并且每次ComPtr变量超出范围时,都会自动减少ref-count。这极大地简化了错误处理和清理,这就是为什么您所看到的代码在调用Release
时不会出现泛滥的原因。
对于'转让所有权'有一些特殊的方法Attach
和Detach
,这样ref-count不会改变,但它们是针对特殊用例的。您也可以使用Swap
做一些技巧,这对于强大的编码非常有用。
如果你想明确'释放'一个ComPtr变量,你可以给它分配null或者更好地使用Reset
。
与所有smart-pointers一样,您应该考虑指针的生命周期以决定如何使用它。如果一个函数或类要“拥有”指向的对象,那么使用智能指针是正确的方法。如果该函数刚刚与对象一起工作,然后在生命周期中没有任何更改地返回,那么函数应该采用原始指针,而不是在调用它时使用ComPtr上的Get
方法。否则,如果对象的所有权实际上没有问题,那么程序会浪费大量时间来不必要地增加和减少ref-count。
另一种选择是智能指针参数传递作为
const ComPtr&
从而避免裁判计数循环,但它迫使呼叫者使用ComPtr
当原料指针是更不可知的调用者的副作用对象生存期策略,因此更加灵活。
我已经写了如何在DirectX Tool Kit wiki上使用ComPtr
。您还可以看到MSDN。
对于非COM对象,
std::unique_ptr
是一个不错的选择。您也可以使用std::shared_ptr
和std::weak_ptr
,但在共享的情况下会涉及很多性能影响和边缘情况,因此对于COM,坚持使用ComPtr
,对于使用单个所有者的堆分配对象,坚持std::unique_ptr
是最佳做法。
您通常不需要通过智能指针调用AddRef
或Release
- ComPtr
的整个点是它为您调用的那些。
如果您将智能指针转换为“手动管理”(普通)指针,您可能仍然需要调用它们。
谢谢! @immibis – CPlusPlusProgrammer
- 1. 使用鼠兔BlockingConnection时,是否basic_ack()必须放置在回调函数
- 2. 释放返回的对象还是我必须使用自动释放
- 3. 我是否必须在read_triplet中释放doublet?我该怎么做?
- 4. 我是否必须使用onPause/onStart/onDestroy
- 5. 我是否必须使用UNION insted JOIN?
- 6. 是否必须使用SSL?
- 7. Swift UnsafeMutablePointer:我必须在释放之前调用deinitialize吗?
- 8. 我是否必须释放弧中的无弧对象?
- 9. “参数必须是可调用函数”当使用scipy.integrate.quad
- 10. 在调用qRegisterMetaType之前,我是否必须调用Q_DECLARE_METATYPE?
- 11. 使用jQuery进行AJAX调用是否必须返回数据?
- 12. 必须释放代码依赖于通过函数调用保留的ebx吗?
- 13. jqGrid.info_dialog不是函数,我必须调用extend吗?
- 14. 使用vlfeat时,我必须明确释放内存吗?
- 15. 我必须释放这个变量吗?
- 16. C++我总是必须使用std :: move来调用移动构造函数吗?
- 17. 在使用之前,类函数/变量是否必须声明?
- 18. 匿名函数是否必须使用括号括起来?
- 19. 用户ID是否必须是整数?
- 20. 是否必须使用@Override注释继承的方法?
- 21. 您是否必须释放ABAddressBookGetPersonWithRecordID的返回值?
- 22. Object Pascal:是否必须释放所有对象(类)?
- 23. 如果我绑定参数,是否必须使用mysql_real_escape_string?
- 24. 我们在使用会话时是否必须使用mysql_real_escape_string()?
- 25. 我是否必须使用Compass使用Django-Grappelli修改CSS?
- 26. 对malloc的调用是否必须通过调用才能在动态内存池中释放?
- 27. 我是否必须在循环函数中使用循环Notes对象?
- 28. 每次使用onMessage.addListener responseCallback时,是否必须调用return true?
- 29. 分配时是否必须使用initWithString?
- 30. Bootstrap Carousel是否必须使用图像?
ComPtr:“创建一个智能指针类型,它表示由模板参数指定的接口.ComPtr自动维护底层接口指针的引用计数,并在引用计数为零时释放接口。源MSDN:https://msdn.microsoft.com/en-us/library/br244983.aspx –