2014-08-28 58 views
1

这里究竟发生了什么?我还以为你不能够/应该复制的unique_ptr然而真实的下面的代码编译并运行正常:通过函数创建unique_ptr

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

// Useage 
auto MySomeObject = CreateObject(); 

上调用此的unique_ptr的移动方法?如果是这样,是否有一种方法可以在函数内实际创建unique_ptr,并在函数作用域退出时不返回对象,而返回它?

我宁愿不返回实际指针,然后把它变成一个unique_ptr,以强制使用此函数返回的对象的unique_ptrs。我也不想仅仅使用shared_ptr来避免这个问题中提出的问题。

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

+1

它不是复制'unique_ptr',而是**移动它。因此,该对象在“MySomeObject”被销毁之前不会被销毁。另外,如果上述情况产生任何开销,我会感到惊讶,因为RVO很可能会确保“MySomeObject”被直接初始化,而无需调用任何move-ctor。 – 2014-08-28 10:30:35

+0

谢谢,这里绝对让我放心。我希望你已经发布作为答案,所以我可以接受它。 – KKlouzal 2014-08-28 10:37:23

+0

这是之前被问过的,但我无法找到以前的实例。 – 2014-08-28 10:46:00

回答

3

我还以为你不能够/应该复制的unique_ptr的

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

是否调用了unique_ptr的移动方法?

是的。尽可能移动函数的返回值;并且临时返回值的分配也通过移动完成。

有没有一种方法可以在函数内实际创建unique_ptr,并在函数作用域退出时返回它而不会破坏对象?

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

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

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

  • 置零的指针时,它从移动;
  • 检查指针销毁时是否删除对象。

这些都不太可能是重要的,特别是当与new的成本相比时。

+0

关于性能点:编译器可能会检测到赋值没有效果,并且不需要检查。分析可能会提供有关性能方面的见解。 – johannes 2014-08-29 14:51:35