[英]Transferring sole ownership: unique_ptr vs move semantics
似乎std::unique_ptr
解決了一個問題,也可以通過移動語義來解決,即轉移獨有資源的所有權。 以下是他們似乎執行相同工作的一些示例:
class SomeResource { /* resourcey stuff */ };
void ProcessResourcePtr(std::unique_ptr<SomeResource> r) { /* do stuff */ }
void ProcessResourceRvalRef(SomeResource&& r) { /* do stuff */ }
class OwnerOfResourcePtr {
private:
std::unique_ptr<SomeResource> r_;
public:
OwnerOfResourcePtr(std::unique_ptr<SomeResource> r) : r_(std::move(r)) { }
};
class OwnerOfResourceRvalRef {
private:
SomeResource r_;
public:
OwnerOfResourceRvalRef(SomeResource&& r) : r_(std::move(r)) { }
};
int main()
{
// transfer ownership to function via unique_ptr
std::unique_ptr<SomeResource> r1(new SomeResource());
ProcessResourcePtr(std::move(r1));
// transfer ownership to function via rvalue ref
SomeResource r2;
ProcessResourceRvalRef(std::move(r2));
// transfer ownership to instance via unique_ptr
std::unique_ptr<SomeResource> r3(new SomeResource());
OwnerOfResourcePtr(std::move(r3));
// transfer ownership to instance via rvalue ref
SomeResource r4;
OwnerOfResourceRvalRef(std::move(r4));
return 0;
}
在我看來,這兩者都以稍微不同的方式解決了幾乎完全相同的問題。 我不是100%清楚單向與對方的優勢。 我知道指針移動可能比移動構造函數/賦值更快,盡管通常認為兩者都非常有效。 我也知道移動語義允許你將數據保存在堆棧上(參見r2,r4)而不是要求使用new / malloc / etc(參見r1,r3)進行堆分配/釋放,我認為這是一個好的事(是嗎?)。
通常什么時候應該更喜歡unique_ptr
over move語義,反之亦然? 是否有任何用例只能由一個或另一個解決?
如果你有一個沒有移動構造函數的類(可能由其他人編寫),甚至可能不是復制構造函數,那么你可能必須使用unique_ptr
。
如果實例是可選的,即可能不存在,則應使用unique_ptr
。
如果只能在調用構造函數后初始化對象,並且該對象不是默認構造的,則必須延遲構造,並且可以使用unique_ptr
。
即使一個類有一個移動構造函數,這可能比移動單個指針更昂貴。 例如,如果該類包含許多POD實例或數組。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.