【问题标题】:Creating unique_ptr Via Functions通过函数创建 unique_ptr
【发布时间】:2014-10-22 04:20:34
【问题描述】:

这里到底发生了什么?我认为您无法/不应该复制 unique_ptr,但是以下代码可以正常编译和运行:

std::unique_ptr<SomeObject> CreateObject()
{
    return std::unique_ptr<SomeObject>(new SomeObject);
}

//  Useage
auto MySomeObject = CreateObject();

是否调用了 unique_ptr 的 move 方法?如果是这样,有没有办法在函数内部实际创建 unique_ptr 并在函数范围退出时对象不会被破坏的情况下返回它?

我宁愿不返回实际指针,然后将其转换为 unique_ptr 以强制对该函数返回的对象使用 unique_ptrs。我也不想使用 shared_ptr 来避免这个问题中提出的问题。

这是应用程序的一个非常关键的性能区域,我担心这里可能会产生额外的开销。

【问题讨论】:

  • 不是在复制unique_ptr,而是在移动它。因此,在 MySomeObject 被销毁之前,该对象不会被销毁。另外,如果上面的内容产生任何开销,我会感到惊讶,因为 RVO 很可能会确保直接初始化 MySomeObject 而无需调用任何 move-ctor。
  • 谢谢,这绝对让我放心。我希望您已将其作为答案发布,以便我接受。
  • 之前有人问过这个问题,但我无法找到上一个实例。
  • 更重要的是,我想说最后一段是 Wrong™。复制一个 unique_ptr 最多和移动一个一样慢。你应该担心的是,复制一个 unique_ptr 会导致语义中断,而不是慢代码。
  • CreateObject 背后的概念是 C++14 的一部分,称为 std::make_unique

标签: c++ c++11 unique-ptr


【解决方案1】:

我认为你不能/不应该复制 unique_ptr 的

确实不能。但是您可以移动它们,将托管对象的所有权从一个智能指针转移到另一个。

unique_ptr 的 move 方法是否被调用?

是的。如果可能,移动函数的返回值;而临时返回值的赋值也是通过移动来完成的。

有没有办法在函数内部实际创建unique_ptr 并在函数范围退出时对象不会被破坏的情况下返回它?

是的,这正是这里发生的事情。移动unique_ptr 转移托管对象的所有权;所以在这里,所有权从返回表达式的临时值转移到返回值,转移到MySomeObject。 (实际上,第一步会被省略;但效果是一样的)。

这是应用程序的一个非常关键的性能区域,我担心这里可能会产生额外的开销。

移动unique_ptr 与复制原始指针相比的额外开销是:

  • 从指针移出时将其归零;
  • 检查指针被销毁时是否删除对象。

其中任何一个都不太可能很重要,尤其是与new 的成本相比。

【讨论】:

  • 关于性能点:可能编译器可以检测到赋值无效并且不需要检查。分析可能会提供有关性能方面的见解。
猜你喜欢
  • 2015-10-24
  • 1970-01-01
  • 1970-01-01
  • 2019-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多