7

這裏是一個非常簡單的方法來定義一個移動構造函數用於幾乎所有類移動分配:通過破壞+移動構造安全地移動任務嗎?

class Foo { 
public: 
    Foo(Foo&& foo);      // you still have to write this one 
    Foo& operator=(Foo&& foo) { 
    if (this != &foo) {    // avoid destructing the only copy 
     this->~Foo();     // call your own destructor 
     new (this) Foo(std::move(foo)); // call move constructor via placement new 
    } 
    return *this; 
    } 
    // ... 
}; 

這是程序調用自己的析構函數,然後放置在this指針安全新標準C++ 11 ?

+2

你的移動構造函數最好是'noexcept',否則你將試圖銷燬一個已經被銷燬的對象,如果它在UB-land中拋出並且漫步。 – ildjarn

+1

移動/複製分配的一個好方法是簡單地[按值取參數](http://stackoverflow.com/questions/9746748/does-it-make-sense-to-reuse-destructor-logic-by-使用-stdswap-IN-A-MOVE-分配/ 9746772#9746772)。用戶將移動構建值參數或複製構建它(或者隱藏)。然後您可以使用'std :: swap'將該值交換到您的對象中。 –

回答

6

只有你永遠不會從這個類派生出一個類型。如果你這樣做,這會把對象變成怪物。不幸的是,標準使用這個例子來解釋對象的生命週期。在真實世界的代碼中這是一件非常糟糕的事情。

+0

使用新分配的內存還有問題,請手動操作,然後放置新內存?我必須進行標準研究,檢查這是否允許我自己。 – Yakk

+0

@Yakk不,因爲你沒有[de]分配任何東西。 –

+0

@Yakk不,在這方面應該沒有問題,只要你最初分配的對象的大小和對齊要求足以滿足你通過placement new創建的對象,並且你傳遞給刪除的指針是合適的類型。 – bames53

0

從技術上講,源代碼在這個小例子中是安全的。但事實是,如果你甚至看到Foo有趣,你會調用UB。這是非常不安全的,完全不值得。只需像其他人一樣使用交換 - 這是有原因的,這是因爲這是正確的選擇。而且,自我分配檢查是不好的。

+2

複製和交換並不總是最好的實現。這是獲得強有力的例外安全保證的一個簡單方法,但是存在權衡。 Howard Hinnant在[this](http://stackoverflow.com/a/6687520/365496)的一部分中對此進行了部分討論。 – bames53

+0

你關心的主要是派生類作者(在這種情況下是錯誤的)調用Foo移動作業,還是存在比這更多的問題?該技術確實需要子類作者虛擬覆蓋並使用該技術。我能想到的大多數問題都涉及到移動分配不是虛擬的,因此答案只是移動分配在這些情況下應該是虛擬的,無論這種技術是否被使用(您是否同意?)。除此之外,你還有什麼擔憂嗎? –