shared_ptr 的原始指针构造函数是错误的吗?

2024-06-06

事后看来,鉴于make_shared, would shared_ptr是否有一个采用原始指针的构造函数(如果它是在 C++11 中引入的)?

是否有强有力的论据或用例支持此构造函数?

它将避免有据可查的陷阱异常安全 https://herbsutter.com/gotw/_102/内存分配/性能优势 http://en.cppreference.com/w/cpp/memory/shared_ptr#Implementation_notes使用的make_shared.

我相信要求的另一个好处shared_ptr施工通过make_shared它可能是幕后的单个指针,降低其内存使用量并使得诸如原子比较交换 http://en.cppreference.com/w/cpp/memory/shared_ptr/atomic更简单(并且可能更有效)。 (看来自 C++Now 的演示 https://github.com/brycelelbach/cppnow_presentations_2016/raw/master/01_wednesday/implementing_a_lock_free_atomic_shared_ptr.pdf)

我知道基本上是一个 intrusive_ptr (对象和控制块合并)的 shared_ptr 将缺乏当前 std::shared_ptr 所具有的功能。喜欢:

  1. 能够从控制块中单独释放对象(如果您长期使用weak_ptrs,这很好)

  2. 与为您提供原始指针的库的兼容性以及释放它们的责任

  3. 使用自定义删除器(或无删除器,对于非拥有指针)保存任意资源的能力

  4. 能够在保持父对象活动的同时指向子对象(例如,成员)。

我的建议是,这些功能可能不会被广泛使用(或者在将其用作RAII https://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization-wrapper)可能不是最合适的,以保证额外的费用:

  1. 指向控制块的单独指针
  2. (可能)更复杂的atomic_compare_exchange逻辑,可能不值得。

In a C++98 https://en.wikipedia.org/wiki/C%2B%2B#Standardizationworld(引入了shared_ptr) make_shared 不太实用,也不太用户友好(缺乏完美的转发需要引用包装器,并且缺乏可变参数模板使得实现变得笨拙)。


你的逻辑问题在于你相信原因shared_ptr托管指针和托管指针之间有区别get指针是因为make_shared不可用。因此,如果我们强迫每个人都使用make_shared创造shared_ptr,我们不需要这种区别。

这是不正确的。

你可以实施shared_ptr的基于指针的构造函数没有这种区别。毕竟,在最初创建托管时shared_ptr, the get指针和托管指针是相同的。如果你想要shared_ptr成为sizeof(T*),你可以只拥有shared_ptr获取get来自托管块的指针。这与是否T嵌入在托管块中。

所以区别确实有什么都没有make_shared及其嵌入的能力T与托管块位于同一内存中。或者更确切地说,缺乏它。

不,托管指针和托管指针之间的区别get指针被创建,因为它添加了features to shared_ptr。重要的。您列出了其中一些,但错过了其他一些:

  • 有能力拥有shared_ptr到基类。那是:

    shared_ptr<base> p = make_shared<derived>(...);
    

    要做到这一点,你must特定实例指向的内容和控制块控制的内容之间存在区别。

  • static_pointer_cast and dynamic_pointer_cast (and reinterpret_pointer_cast在 C++17 中)。这些都依赖于托管指针和托管指针之间的区别get指针。

    • 这还包括enable_shared_from_this在基类中。
  • A shared_ptr指向本身由 a 管理的类型的成员子对象shared_ptr。同样,它要求托管指针不能与get指针。

您似乎还忽略了管理不是由您创建的指针的能力。那是一个critical能力,因为它允许您与其他代码库兼容。在内部,您可以使用shared_ptr管理 1998 年编写的库所做的事情。

按照您的方式,您可以将代码分为两个时期:C++11 之前和 C++11 之后。你的shared_ptr对于任何未明确为 C++11 编写的代码不会执行任何操作。

将所有这些功能包装成一个类型的好处是:

你不需要另外一个。

shared_ptr,因为它满足了如此多的需求,所以几乎可以在任何地方有效地使用。它可能不是绝对最有效的类型,但是will几乎在所有情况下都能完成这项工作。而且这样做的速度并不慢。

它通过多态性处理共享所有权。它处理成员对象的共享所有权。它处理您未分配的内存的共享所有权。它处理具有特殊分配/释放需求的内存共享所有权。等等。

如果您需要共享所有权语义,并且需要它work, shared_ptr每次都会为您提供支持。根据你提出的想法,总会有一些限制,一些东西会妨碍你完成工作。

默认情况下,应该优先选择一种有效的类型,而不是无效的类型。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

shared_ptr 的原始指针构造函数是错误的吗? 的相关文章

随机推荐

  • 是否可以合理地解决防病毒扫描工作目录的问题?

    我的 Win32 应用程序在运行时在指定的临时文件夹中执行大量磁盘操作 并且认真地重新设计它是不可能的 某些客户端具有扫描同一临时目录的防病毒软件 它只是扫描所有内容 我们试图说服他们禁用它 它不起作用 所以它也是不可能的 每隔一段时间 例
  • Firebreath 插件未在 IE 10 中加载

    EDIT 请参阅帖子末尾以获取更多信息 I am trying to to get plugins created via the Firebreath framework 1 7 0 to load I am on Windows 8 i
  • 将结果从 pdo 发送到 ajax 时遇到问题

    我想做的是 如果用户成功注册 pdo 将提供信息并将其发送到 ajax 如果用户注册与否 ajax 将发送消息 在我将这个条件放入我的 pdo 中后 它工作正常 现在它不会再插入 并且 ajax 告诉 注册用户时出错 每时每刻 script
  • 我可以从列 CHECK 约束调用用户定义的函数吗?

    我有一个返回 1 或 0 的用户定义的 SQL 函数 我想从列 CHECK 约束中调用它 是的 SQL Anywhere 没有布尔数据类型 因此您必须编写一个生成 TRUE FALSE 或 UNKNOWN 的谓词 换句话说 如果函数返回 1
  • 水线,在数组中查找数组

    我有视频模型 module exports attributes id string tags array 我想查找带有 Hello 或 World 等标签的所有视频 我可以轻松获取所有视频 例如 Video find tags 你好 我看
  • 使用 Servlet 3.0 上传文件时 request.getParameter() 是否仍然有效?

    我刚刚读过这个很好的答案 https stackoverflow com questions 2422468 how to upload files in jsp servlet 2424824 2424824来自 BalusC 关于如何使
  • 使用 pandas 中的 chunksize 参数提取每个值的基本计数

    我有一个包含以下类别的 CSV 文件 item1 item2 item3 item4其中值恰好是以下之一 0 1 2 3 4 我想计算每个项目的每个值有多少个 我的代码如下 df是相应的DataFrame outputDf pandas D
  • 以编程方式更改 PDF 文件中黑框的颜色?

    我有一个由 Microsoft Word 生成的 PDF 文件 用户指定了黑色的 突出显示 颜色 使文本看起来像一个黑框 并使文本看起来像是经过编辑的 我想将黑框更改为黄色 以便突出显示文本 理想情况下 我想用 Python 来完成此操作
  • 如何使用 PHP 向用户发送每日电子邮件通知?

    我有一个简单的用户注册表单 其中有一个复选框 如果用户的任何项目有活动 用户可以每天收到电子邮件通知 就像 Stack Overflow 有一个 通知 电子邮件受保护 cdn cgi l email protection每天都有新的答案 我
  • 如何列出我使用 Cargo install 全局安装的所有软件包?

    我已经使用安装了几个 CLI 工具cargo install 例如 ripgrep 如何查看我使用的下载的所有包的列表cargo install 有点像apt list installed但对于cargo 命令行 cargo help in
  • 启动注册期间无法加载程序集“System.Buffers”

    我的 Xamarin 表单应用程序大约 5 分钟前运行 然后突然停止工作 应用程序启动后立即关闭 下面显示了 Visual Studio 输出中的消息显示 Assembly Loader probing location System Bu
  • TFS Rest API 签入版本控制

    我需要能够从 VSTS 扩展签出 编辑和签入 本地 TFVC TFS 存储库 v2015 3 在文档中https www visualstudio com en us docs integrate api tfvc overview htt
  • 使用相同图像映射的多个图像 - 如何在单击时返回正确的图像参考?

    我在一个页面上有多个图像 所有图像都使用相同的图像映射 我需要知道用户点击了哪个图像 问题是 this 返回对的引用 area 而不是 img 这是代码 img src image png img src image png img src
  • 将 pandas 多索引折叠为单个索引

    我有一个多索引的 Pandas 数据框 如下所示 如何将三层索引合并为一层索引 也就是说 我想将 1987 1 2 转换为 pd datetime 1987 1 2 我更喜欢使用 df index map 的矢量化方法 以下是可以创建数据框
  • 了解 IServiceProvider 和 QueryService

    谁能解释一下背后的想法IServiceProvider and QueryService 我不明白服务是什么以及它与其他类型的对象或接口有何不同 我看到的解释很少 主要是一些评论here https learn microsoft com
  • 使用 jQuery 选择焦点文本在 Safari 和 Chrome 中不起作用

    我有以下 jQuery 代码 类似于这个问题 https stackoverflow com questions 480735 在 Firefox 和 IE 中工作 但在 Chrome 和 Safari 中失败 没有错误 只是不起作用 有解
  • Jenkins - 配置 Jenkins 以轮询 SCM 中的更改

    我正在与 jenkins 合作 当 svn 存储库发生更改时 我想运行 Maven 目标 我附上了一张我当前配置的图片 我知道每 5 分钟检查一次存储库是疯狂的 我想只有当有新的变化时才运行它 但我找不到方法 无论如何 它不会检查存储库 我
  • 服务器未配置 RPC

    查找我的工作历史 发现以下错误 06 18 2018 00 00 01 MBS Lojas ExportaMR OutrasLojas Error 1 WIN VRT 01 SQL2008 MBS Lojas ExportaMR Outra
  • 使用数组参数创建 bash 选择菜单

    我有一个函数叫做createmenu 该函数将接受一个数组作为第一个参数 第二个参数是数组的大小 然后我想使用该数组的元素创建一个选择菜单 这是我到目前为止所拥有的 使用给定数组创建菜单 createmenu echo 1 echo Siz
  • shared_ptr 的原始指针构造函数是错误的吗?

    事后看来 鉴于make shared would shared ptr是否有一个采用原始指针的构造函数 如果它是在 C 11 中引入的 是否有强有力的论据或用例支持此构造函数 它将避免有据可查的陷阱异常安全 https herbsutter