簡體   English   中英

std::move 在 unique_ptr 和它擁有的另一個之間

[英]std::move between unique_ptr and another that it owns

考慮一些類/結構

struct Foo{
    int val = 0;
    std::unique_ptr<Foo> child_a = NULL;
    std::unique_ptr<Foo> child_b = NULL;
    Foo(int val_):val(val_){}
    ~Foo(){std::cout<<"Deleting foo "<<val<<std::endl;}
};

正如您可能在雙向鏈表/二叉樹或類似結構中構建的那樣。

現在,考慮在這樣一個列表中,我們有幾個這樣的Foo以樹狀方式相互指向,例如通過

std::unique_ptr<Foo> root = std::make_unique<Foo>(Foo(0));
root->child_a = std::make_unique<Foo>(Foo(1));
root->child_b = std::make_unique<Foo>(Foo(2));
root->child_a->child_a = std::make_unique<Foo>(Foo(3));
root->child_a->child_b = std::make_unique<Foo>(Foo(4));
root->child_b->child_a = std::make_unique<Foo>(Foo(5));
root->child_b->child_b = std::make_unique<Foo>(Foo(6));

在這種情況下,如果我寫

root = NULL

然后所有鏈接的孩子都被刪除,我得到 output 看起來像

Deleting foo 0
Deleting foo 1
Deleting foo 3
Deleting foo 4
Deleting foo 2
Deleting foo 5
Deleting foo 6

那么我的問題是,當我做這樣的事情時到底發生了什么

root = std::move(root->child_a);

output 在這種情況下看起來像

Deleting foo 0
Deleting foo 2
Deleting foo 5
Deleting foo 6

正如人們所希望的那樣,只留下child_a分支代替原始root

但是看着這個,我意識到我並不完全確定std::move在這里是如何工作的,而且“預期的行為”似乎真的把自我參照的舉動視為理所當然。 我一直廣泛認為這樣的舉動

a=std::move(b);

功能非常粗略

a = NULL;
b.release();
a.get() = b.get();

但當然這不可能在這里,因為第一個NULL在替換剛剛刪除的a之前會破壞b

相反,我想像這樣的事情正在發生

b.release();
c = b.get();
a = NULL;
a.get() = c;

這樣b被移動到一些新的原始指針c以便可以刪除a而不會干擾原始b

但是花了一些時間嘗試嘗試弄清楚這里發生了什么,我仍然不確定,當a)閱讀具有此類用途的代碼而b)我的絕大多數教程時,這有點令人不安可以在 unique_ptrs 上找到,只是不要提及將嵌套指針相互移動時會發生什么。

任何人都可以詳細說明這里實際發生的事情,也許可以為我指出一個好的資源嗎?

來自cppreference

std::unique_ptr<T,Deleter>::reset

無效重置(指針 ptr = 指針())noexcept;

給定由 *this 管理的指針 current_ptr,按以下順序執行以下操作:

  1. 保存當前指針 old_ptr = current_ptr 的副本
  2. 用參數 current_ptr = ptr 覆蓋當前指針
  3. 如果舊指針非空,則刪除先前管理的 object if(old_ptr) get_deleter()(old_ptr)。

std::unique_ptr<T,Deleter>::operator=

unique_ptr& operator=( unique_ptr&& r ) noexcept;

移動賦值運算符。 將所有權從 r 轉移到 *this,就好像通過調用reset(r.release())然后從 std::forward<Deleter>(r.get_deleter()) 分配 get_deleter()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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