我应该使用shared_ptr还是unique_ptr

2023-12-31

我一直在使用 pimpl 习惯用法制作一些对象,但我不确定是否使用std::shared_ptr http://en.cppreference.com/w/cpp/memory/shared_ptr or std::unique_ptr http://en.cppreference.com/w/cpp/memory/unique_ptr.

我明白那个std::unique_ptr效率更高,但这对我来说并不是什么大问题,因为这些对象无论如何都是相对重量级的,所以成本std::shared_ptr over std::unique_ptr是相对较小的。

我目前正在与std::shared_ptr只是因为额外的灵活性。例如,使用std::shared_ptr允许我将这些对象存储在哈希图中以便快速访问,同时仍然能够将这些对象的副本返回给调用者(因为我相信任何迭代器或引用可能很快就会变得无效)。

然而,这些对象在某种程度上确实没有被复制,因为更改会影响所有副本,所以我想知道也许使用std::shared_ptr允许复制是某种反模式或坏事。

它是否正确?


我一直在使用 pimpl 习惯用法制作一些对象,但我不确定是否使用shared_ptr or unique_ptr.

确实unique_ptr or scoped_ptr.

Pimpl不是一种模式,而是一种习惯用法,它处理编译时依赖性和二进制兼容性。它不应该影响对象的语义,特别是在其复制行为方面。

您可以在幕后使用您想要的任何类型的智能指针,但这两个保证您不会意外地在两个不同的对象之间共享实现,因为它们需要对复制构造函数和赋值运算符的实现有意识的决定。

然而,这些对象在某种程度上确实没有被复制,因为更改会影响所有副本,所以我想知道也许使用shared_ptr允许复制是某种反模式或坏事。

它不是一种反模式,事实上,它是一种模式:别名。您已经在 C++ 中通过裸指针和引用使用了它。shared_ptr提供额外的“安全”措施来避免死引用,但代价是额外的复杂性和新问题(小心造成内存泄漏的循环)。


与Pimpl无关

我明白unique_ptr效率更高,但这对我来说并不是什么大问题,因为这些对象无论如何都是相对重量级的,所以成本shared_ptr over unique_ptr是相对较小的。

如果您可以分解出某些状态,您可能需要查看蝇量级 http://www.vincehuston.org/dp/flyweight.html图案。

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

我应该使用shared_ptr还是unique_ptr 的相关文章

  • 如何使用 ASP.NET MVC 进行 HTTP 调用?

    我正在尝试做的事情 我试图练习进行 HTTP 调用 如果这就是它的名字 来自一个简单的 ASP NET MVC Web 应用程序 为此 我尝试从以下位置获取天气详细信息打开天气地图 http openweathermap org appid
  • OpenCV Visual Studio ntdll.dll

    我尝试在 Visual Studio 2013 上使用 OpenCV 2 4 10 创建一个项目 但由于以下异常 到目前为止我运气不佳 请建议帮助 TIA letstryitonemoretime exe Win32 Loaded C Us
  • 隐式方法组转换陷阱

    我想知道为什么给定代码的输出 在 LinqPad 中执行 void Main Compare1 Action Main Dump Compare2 Main Dump bool Compare1 Delegate x return x Ac
  • 泛型与接口的实际优势

    在这种情况下 使用泛型与接口的实际优势是什么 void MyMethod IFoo f void MyMethod
  • C++ 非类型参数包扩展

    我正在编写由单一类型参数化的模板函数 并且具有可变数量的相同类型 而不是不同类型 的参数 它应该检查第一个值是否在其余值中 我想这样写 include
  • 如何从 List 中的字符串中删除数字/数字?

    我有一个字符串列表 List
  • 异步方法中的异常未被捕获

    下面的代码没有捕获我的OperationCancelEException 它是通过调用抛出的ct ThrowIfCancellationRequested public partial class TitleWindow Window IA
  • C++ 中的 Java ArrayList [重复]

    这个问题在这里已经有答案了 在Java中我可以做 List
  • C 中“for”循环中的两个变量

    我正在编写一些代码 需要在其中使用两个变量for环形 下面的代码看起来没问题吗 它确实给了我预期的结果 for loop 1 offset loop 2 offset 2 loop 1 gt offset 190 loop 2 lt 190
  • 控制器中的异常处理 (ASP.NET MVC)

    当您自己的代码抛出异常并从控制器中的操作调用时 应该如何处理 我看到很多最佳实践的例子 其中根本没有 try catch 语句 例如 从存储库访问数据 public ViewResult Index IList
  • 如何防止字符串被截留

    我的理解 可能是错误的 是 在 C 中 当你创建一个字符串时 它会被实习到 实习生池 中 这保留了对字符串的引用 以便多个相同的字符串可以共享操作内存 但是 我正在处理很多很可能是唯一的字符串 一旦完成每个字符串 我需要将它们从操作内存中完
  • 以标准用户身份打开默认浏览器 (C++)

    我目前正在使用 ShellExecute 打开 在用户浏览器中打开 URL 但在 Win7 和 Vista 中遇到了一些麻烦 因为该程序作为服务运行提升 当 ShellExecute 打开浏览器时 它似乎读取 本地管理员 配置文件而不是用户
  • 如何用C++解析复杂的字符串?

    我试图弄清楚如何使用 解析这个字符串sstream 和C 其格式为 string int int 我需要能够将包含 IP 地址的字符串的第一部分分配给 std string 以下是该字符串的示例 std string 127 0 0 1 1
  • C# 的空条件委托调用线程安全吗? [复制]

    这个问题在这里已经有答案了 这就是我一直以来编写事件引发者的方式 例如属性更改 public event PropertyChangedEventHandler PropertyChanged private void RaisePrope
  • 我应该使用多个 HttpClient 来进行批量异步 GET 请求吗?

    我有一个场景 我需要在尽可能短的时间内发出大量 GET 请求 想想大约 1000 个 我知道通常最好保留一个客户端并尽可能重用它 Create Single HTTP Client HttpClient client new HttpCli
  • 如何使用简历实现一个“一网打尽”的异常处理程序?

    我想知道我怎样才能写一个抓住他们全部应用程序级别的异常处理程序将为用户提供恢复应用程序流程的选项 如果您正在运行 Windows 窗体应用程序 将处理程序添加到Application ThreadException event
  • 将小数格式化为两位或整数

    对于 10 我想要 10 而不是 10 00 对于 10 11 我想要 10 11 没有代码可以实现吗 即通过指定格式字符串类似于 0 N2 decimal num 10 11M Console WriteLine num ToString
  • 在类中使用 std::chrono::high_resolution_clock 播种 std::mt19937 的正确方法是什么?

    首先 大家好 这是我在这里提出的第一个问题 所以我希望我没有搞砸 在写这篇文章之前我用谷歌搜索了很多 我对编码 C 很陌生 我正在自学 考虑到有人告诉我 只为任何随机引擎播种一次是一个很好的做法 我在这里可能是错的 什么是正确 最佳 更有效
  • 编译器可以报告未知属性的错误吗?即使有范围?

    在N3291 7 6 1 3 5 属性语法和语义 decl attr grammar 关于如何属性是用我读过的源代码写的 使用一个属性范围令牌是有条件支持的 实现定义的行为 and For an 属性标记本国际标准中未指定 该行为是实现定义
  • FakeItEasy 代理方法调用实际实现

    我正在尝试将对假对象的调用代理到实际的实现 这样做的原因是我希望能够使用 Machine Specifications 的 WasToldTo 和 WhenToldTo 它们仅适用于接口类型的伪造 因此 我正在执行以下操作来代理对我的真实对

随机推荐