簡體   English   中英

轉移唯一所有權:unique_ptr vs move語義

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM