2014-08-28 86 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