【问题标题】:Is there any situation in which I wouldn't use std::make_shared?有没有我不会使用 std::make_shared 的情况?
【发布时间】:2013-10-14 11:12:48
【问题描述】:

根据我所做的研究,听起来std::make_shared 是构造std::shared_ptr 的首选方式。具体是因为:

  1. 与使用至少执行两次的new 相比,它只执行一次内存分配。
  2. 如果传递给 make_shared throws 的 ctor 不会泄漏,就像使用 new 时一样。

我的问题是,假设我想要一个 shared_ptr,我应该始终使用make_shared,还是在某些情况下首选new?

【问题讨论】:

  • shared_ptr<int>(new int) 不会在 shared_ptr 构造函数抛出时泄漏内存;这就是你的第二点对我的暗示。

标签: c++ memory-management c++11 shared-ptr smart-pointers


【解决方案1】:

由于计数器和对象共享相同的分配,它们也共享相同的释放。

计数器必须持续到最后一个 shared_ptr 和 weak_ptr 消失。如果您有一个大对象(或许多小对象)和持久的weak_ptrs,如果您通过make_shared 分配shared_ptrs,这可能会导致内存争用。

其次,如果您有一个向您提供指针或资源句柄的 3rd 方 API,并且可能具有自己的处置功能,那么 make_shared 既不合适也不可能在每种情况下都使用。创建您自己的 make_ 函数可以避免杂乱的细节让您处理这个问题,也可以处理异常极端情况。

最后,虽然共享指针很棒,但它们也过于强大。很多时候我想要一个unique_ptr 甚至是boost::scoped_ptr,或者一个侵入式引用计数指针,或者类似的东西来表示所有权。 shared_ptr 应该仅在实际涉及资源的共享所有权的情况下使用:因为它“简单”而随意使用它往往会导致资源等价于意大利面条代码。

【讨论】:

  • 最后一段加分。虽然这个问题没有直接解决,但在这种情况下不能经常说。
【解决方案2】:

您可能必须处理返回动态分配对象的遗留代码。在这种情况下,您需要将 std::shared_ptr<T> ctor 与指针参数一起使用。使用 std::make_shared 并不可取,但它确实允许您将所有 std::shared_ptr<T> 优点与旧代码一起使用。

我知道这并不完全等同于直接使用 new 和 std::shared_ptr<T> ctor,但它是 std::shared_ptr<T> 的有效用例,其中无法使用 make_shared。

【讨论】:

    【解决方案3】:

    我对你的问题的解释有点不确定。我假设使用shared_ptr<T> 是合理的;关于你不想使用shared_ptr 的原因,我只能排在Yakk 后面。

    有一种情况,不能使用make_shared或allocate_shared来构造shared_ptr,但需要使用对应的ctor:如果需要传入自定义删除器,见(3)和(4 )the ctors of shared_ptr。

    【讨论】:

      【解决方案4】:

      我在具有私有构造函数(来自静态工厂方法)的类上使用 make_shared 时遇到了问题。我不认为有一个简单的解决方案。

      【讨论】:

      • 我认为这方面存在缺陷;您应该能够将make_shared 设为好友功能吗?该标准是否有效尚不清楚。
      • 我做了一个解决方法,让您可以将make_shared 与“私有”构造函数一起使用:ideone.com/O93w6o
      【解决方案5】:

      我应该一直使用 make_shared,还是在某些情况下 new 是 首选

      make_shared 是不允许的,当我们将裸指针存储在由其他人分配的 shared_ptr 中时。它只能调用public 构造函数。但是,一些编译器中有一些关于使用 make_shared like this 访问受保护构造函数的报告。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-10
        • 2021-09-14
        • 1970-01-01
        • 1970-01-01
        • 2015-12-05
        • 2019-01-14
        • 2020-10-19
        • 1970-01-01
        相关资源
        最近更新 更多