30

下面的snipplet是否適用於爲類定義所有其他方法生成的方法和構造函數?在類中正確使用`= delete`方法

struct Picture { 

    // 'explicit': no accidental cast from string to Picture 
    explicit Picture(const string &filename) { /* load image from file */ } 

    // no accidental construction, i.e. temporaries and the like 
    Picture() = delete; 

    // no copy 
    Picture(const Picture&) = delete; 

    // no assign 
    Picture& operator=(const Picture&) = delete; 

    // no move 
    Picture(Picture&&) = delete; 

    // no move-assign 
    Picture& operator=(Picture&&) = delete; // return type correct? 
}; 

這將刪除每個默認的編譯器實現,只留下析構函數,對不對?如果沒有它,我猜可能會(幾乎)不可用,但我可以刪除它,對嗎?

返回類型Picture&的移動分配operator=(Picture&&)是否正確?如果我爲返回類型寫了Picture&&,它會有所作爲嗎?

+3

看起來好像C++在C++ 0x!中真的改變了很多,有趣的東西。 – briantyler 2011-04-16 14:19:55

+1

這是一個更清晰的語法,然後將這些方法隱藏在「private」部分中,並且只聲明*但不定義*它們。 – towi 2011-05-27 08:03:39

回答

26

除了Xeo的回答:

是的,一切都是正確的。如果你想,你可以消除所有被刪除的成員,但被刪除的拷貝構造函數和刪除拷貝賦值,並有同樣的效果:

struct Picture { // Also ok 

    // 'explicit': no accidental cast from string to Picture 
    explicit Picture(const string &filename) { /* load image from file */ } 

    // no copy 
    Picture(const Picture&) = delete; 

    // no assign 
    Picture& operator=(const Picture&) = delete; 
}; 

拷貝構造函數的顯式聲明禁止默認構造函數的隱代,移動構造函數和移動賦值成員。明確刪除這些成員是一個有趣的問題。有些人可能認爲它是很好的文檔。其他人可能認爲它過於冗長。

+1

謝謝,我在草稿中忽略了這一點。這節省了打字時間。如果我想要他們,我認爲我可以'他們=默認'? – towi 2011-04-16 17:02:59

+1

是的。你可以明確地默認它們或明確地刪除它們。 – 2011-04-17 03:44:35

3

對我來說似乎很好。 operator=的返回值必須是是一個正常參考,即使該對象是由右值引用構造的。這是因爲你不能只將左值(*this)編譯爲右值。
而且它應該採用每個非常數的右值參考Picture& operator=(Picture&&)。你將如何從一個不變的物體移動? ;)

+0

當然,我多麼愚蠢。你在兩個賬戶上都是對的。讓我在問題中糾正它,所以讀者不從我錯誤的例子中學習。 – towi 2011-04-16 15:27:41