【问题标题】:Should I always use shared_ptr to create a class instance(instead of just new)?我是否应该总是使用 shared_ptr 创建一个类实例(而不仅仅是新的)?
【发布时间】:2019-05-25 14:20:56
【问题描述】:

正如 wiki 所示,shared_ptr 可以处理堆空间回收问题。 所以,我总是用shared_ptr来创建实例,有什么问题吗?

我就这样用,不用delete s吧?

s = std::shared_ptr<S>(new S).get();

【问题讨论】:

  • 这不是您仅有的两个选择。赤裸裸的new 很少是最佳选择,但您还有其他内存管理助手。 std::unique_ptr 通常很有用。如果您有很多对象,您通常可以将管理留给container 等。这取决于您要完成的任务。
  • 好吧,您不必在示例中删除s,它将在同一行中为您删除。 std::shared_ptr(new S) 创建临时的shared_ptr,它在表达式评估期间存在,并且您不将其分配给任何变量。所以它马上就被摧毁了。 shared_ptr 并没有神奇地“处理堆空间回收问题”,你还是要正确使用它。也许 unique_ptr 更好?但这个话题太宽泛,无法评论或单一答案。我建议从这里开始:stackoverflow.com/questions/106508/…
  • 使用unique_ptr,除非您确实需要共享所有权。
  • C++ shared_ptr 模仿 Java 或 C# 的共享引用语义,但根据我的 C++ 经验,拥有更严格的所有权模式要好得多。我尽可能推荐unique_ptr,如果您需要,我推荐shared_ptr,而不是作为首选。
  • 你真的需要指针吗?默认情况下使用S s;,除非您出于某种原因确实需要在堆上使用它。

标签: c++ class memory std shared-ptr


【解决方案1】:

您不应该总是使用shared_ptr,因为more types of smart pointer 不仅仅是shared_ptr。例如,标准库还提供了unique_ptr。您必须评估哪个更适合手头的任务。

然而,智能指针通常是现代 C++ 中安全处理动态分配对象的首选方式。作为一般经验法则,请避免使用newdelete,除非遇到没有它们就无法解决的问题。

顺便说一句,你的例子不会像你期望的那样工作。

auto s = std::shared_ptr(new S).get();

这将创建一个悬空指针。对new 的调用动态分配S 类型的对象。将指向它的指针提供给 shared_ptr 的构造函数,该构造函数现在管理对象生命周期。然后通过get()S 的原始指针的副本分配给s。在行尾,shared_ptr 析构函数释放了S,这意味着s 指向的任何东西都是未定义的。

创建共享指针的正确方法是:

auto s = std::make_shared<S>();

【讨论】:

  • 括号中没有新的 S?要获取实例,我应该使用 s.get()?
  • 你不需要使用new,因为make_shared在内部使用,你只是告诉模板智能指针应该持有什么类型。让库处理它的主要好处是shared_ptr 的控制块和对象本身将被一起分配。如果您使用new 调用shared_ptr 构造函数,您最终会得到可能分配给堆不同部分的控制块和对象。对get() 的调用在某些情况下很有用,例如,如果您需要将原始指针传递给 C 函数。
猜你喜欢
  • 2019-06-29
  • 1970-01-01
  • 1970-01-01
  • 2013-06-13
  • 2021-05-22
  • 1970-01-01
  • 2019-12-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多