gpt4 book ai didi

c++ - shared_ptr 与 CComPtr

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:47:49 25 4
gpt4 key购买 nike

我有点习惯通过 COM 进行引用计数的概念,但我对 shared_ptr 有点陌生。我在 shared_ptr 中没有找到 CComPtr 的几个不错的属性,我想知道防止误用 shared_ptr 的模式是什么。

  • AddRef/Release 模式保证每个对象只有一个引用计数(引用计数存储在对象本身),因此当您有一个随机指针围绕它创建一个 CComPtr 时,它是安全的。另一方面,shared_ptr 有一个单独的 refcount 指针,所以在一个对象上创建一个新的 shared_ptr 是不安全的(为什么标准提供了一个构造函数,它在 shared_ptr 上采用 T* ,如果这样做很不安全?)。这似乎是一个很大的限制,我不明白如何使用 shared_ptr...

  • 有点极端的情况:我过去用 AddRef/Release 做过的事情:我想要一个对 IFoos 的“弱引用”容器(例如从 URL 到 IConnection 的映射或其他)。使用 weak_ptr,我可以做到这一点,但我的集合不会“自行清理”,我将在其中包含过期的指针。使用 Release,我可以实现我自己的弱指针(一些工作)来实际清理集合。是否有 shared/weak_ptr 的替代方案?

  • 直觉上,与只执行一次的 IUnknown 世界相比,执行两次内存分配以创建一个对象(一次用于引用计数,一次用于对象)会降低性能。访问对象时也存在局部性损失(假设 AddRef 之后经常读取对象的内容,这似乎很可能)。是否比较了两种方法的成本?

最佳答案

why does the standard provide a constructor that takes a T* on shared_ptr if it's so unsafe to do?

因为这是获得 shared_ptr 的唯一途径不会打扰。您可以使用 shared_ptr任何。我什至通过使用删除器对象将它们用于 C 接口(interface)的对象。像 cairo_t* 这样的东西等等。这样一来,我就再也不必释放任何东西了。

你不能用 CComPtr 做到这一点;它只适用于 IUnknown -样式对象。

此外,还有 std::make_shared ,它创建了一个 shared_ptr直接从对象类型和构造函数的参数。所以你甚至看不到指针(它通常在一次分配中分配对象及其引用计数,而不是两次)。

正确的 C++ 习语 shared_ptr非常简单:始终使用 make_sharedalloc_shared .如果您不能使用它们,那么正确的习惯用法是将直接裸指针构造函数与new 一起使用。 : shared_ptr<T> pVal{new T{...}}; (或创建指针的适当函数)。永远不要在你不知道来源的指针上使用它。

Is there an alternative with shared/weak_ptr?

没有,但是如果您愿意,可以使用一些工具来制作。除了明显的方法(定期运行您的集合并删除死的 weak_ptr s),您可以将删除器与 shared_ptr 相关联这将(除了删除指针之外)调用任何清理函数来删除那些 weak_ptr

Intuitively, there is a performance penalty in doing two memory allocations to create an object

参见 make_shared , 以上。

There is also a locality penalty when accessing the object (assuming that an AddRef is frequently followed by reading the content of the object, which seems likely).

您不必复制 shared_ptr与其内容对话,也不必为此增加引用计数。

现在,让我们谈谈一些事情CComPtr 不能做。这是侵入性的。它不能与任意分配器或删除器一起使用(当它具有侵入性时显然不那么重要)。它不能做指针别名,你有一个 shared_ptr对象的成员,但实际的引用计数是针对它所属的对象的。这是一件非常有用的事情。

哦,是的,它不是跨平台的。它未绑定(bind)到 COM,IUnknown ,以及所有开销。

关于c++ - shared_ptr 与 CComPtr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9243520/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com