[英]What's the advantage of using move constructor vs passing a pointer?
Foo(Foo&& other) {
this->bar = other.bar;
other.bar = nullptr;
}
Foo(Foo* other) {
this->bar = other->bar;
other->bar = nullptr;
}
上面兩個似乎只是在做同樣的事情。 那么為什么推薦使用移動構造函數呢? 它提供了哪些優勢?
使用正確的移動構造函數的原因有很多:
習俗。 考慮以下代碼:
Foo foo; Foo bar(std::move(foo));
如果您看到該代碼,您將非常清楚您要做什么:您將foo
移到bar
。 相比之下:
Foo foo; Foo bar(&foo);
這是什么意思? 它是否存儲指向另一個Foo
的指針? Foo
是某種鏈表節點類型嗎? 您必須在Foo
的基於指針的構造函數的文檔中查找它。
您無法獲得指向純右值的指針。 Foo bar(Foo{})
將(C++17 之前)創建一個臨時純右值,然后從它移入bar
(移動可以在 C++17 之前省略)。 但是你不能這樣做: Foo bar(&Foo{})
。
您可以從有意義的事物中獲得自動移動。 C++17 的廣義省略使許多這些自動動作消失,但仍有一些:
Foo function() { Foo foo; //Do stuff return foo; }
這將從foo
移動而無需調用std::move
。 原因是foo
是一個即將被銷毀的局部變量。 以這種方式返回它意味着從它移動到返回值是完全合理的。
您的方式需要明確地編寫return &foo
。 這使得auto
返回類型推導變得相當困難。 這樣的函數會推導出Foo*
,這意味着您剛剛返回了一個懸空指針。 而如果你確實return foo;
,它推導出一個Foo
純右值,並自動移動(可能會被忽略)。
不需要nullptr
檢查。 如果您使用Foo*
,則可能有人會傳遞空指針。 而使用參考,則不太可能(而且他們已經調用了 UB)。
如果我們想要對現有語言結構的移動支持,我們只需使用非const
引用來表示“移動”,而不是指針。 通過給它自己的語法,明確什么時候我們在移動什么東西,什么時候我們不移動。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.