【发布时间】:2012-03-03 20:26:00
【问题描述】:
我有点习惯于通过 COM 引用计数的概念,而且我对 shared_ptr 有点陌生。 CComPtr 有几个不错的属性,我在 shared_ptr 中找不到,我想知道防止误用 shared_ptr 的模式是什么。
AddRef/Release 模式保证每个对象只有一个引用计数(引用计数存储在对象本身上),因此当您有一个随机指针围绕它创建一个 CComPtr 时,它是安全的。另一方面,shared_ptr 有一个单独的 refcount 指针,因此在对象上创建新的 shared_ptr 是不安全的(如果这样做不安全,为什么标准提供了一个在 shared_ptr 上接受 T* 的构造函数?)。这似乎是一个很大的限制,我不明白如何使用 shared_ptrs...
有点极端的情况:我过去用 AddRef/Release 做过的事情:我想要一个包含对 IFoos 的“弱引用”的容器(例如从 URL 到 IConnection 的映射或其他东西)。使用weak_ptr,我可以做到这一点,但我的收藏不会“自行清理”,我会在其中包含过期的指针。使用 Release,我可以实现自己的弱指针(一些工作),它实际上会清理集合。 shared/weak_ptr 有替代方案吗?
直观地说,与只执行一次的 IUnknown 世界相比,执行两次内存分配来创建对象(一个用于引用计数,一个用于对象)会降低性能。访问对象时也存在局部性损失(假设 AddRef 之后经常读取对象的内容,这似乎很可能)。是否比较了两种方法的成本?
【问题讨论】:
-
如果您使用
make_shared,则不会产生两次分配。否则,请发布您的实际用例,因为很难凭空争论。shared_ptr很不错,但不是所有情况的唯一解决方案。 -
@KerrekSB:请注意,
make_shared不需要这样做。所有实现都会这样做,但这不是严格要求。 -
与 CComPtr 最大的不同是这个类不需要存储引用计数。它保存在对象中。也不必担心线程,对性能很重要。
标签: c++ com shared-ptr