2012-10-30 71 views
8

可能重複:
How can moved objects be used?
What constitutes a valid state for a 「moved from」 object in C++11?移動的物體應該保持「安全」狀態嗎?

當實現在C++ 11移動語義,應被移至從對象被留在一個安全狀態,或可以它只是處於「垃圾」狀態?

例如在以下C++ 11包裝器的示例中將移動構造器實現爲原始FILE*資源的首選方法是什麼?

// C++11 wrapper to raw FILE* 
class File 
{ 
    FILE* m_fp; 

public: 

    // Option #1 
    File(File&& other) 
    : m_fp(other.m_fp) 
    { 
    // "other" left in a "junk" state 
    } 

    // Option #2 
    File(File&& other) 
    : m_fp(other.m_fp) 
    { 
    // Avoid dangling reference in "other" 
    other.m_fp = nullptr; 
    } 

    ... 
}; 
+0

不會調用'垃圾'對象的析構函數嗎?如果它和析構函數調用'fclose(m_pf)',那麼它肯定會把所有東西搞砸 – 2012-10-30 11:18:57

回答

6

必須能夠與移動,從目標是摧毀它做的唯一的事情。除此之外,這取決於你的班級正常的班級不變量以及移動的物體是否能夠滿足它們。

例如,確保您可以分配給對象是個好主意,以防某人想要在實例上使用std::move並在稍後爲其賦予新值。 [編輯:正如對其中一個建議愚蠢問題的回答中指出的那樣,一般std::swap模板將從一個對象移開,然後移動 - 分配給它,所以如果您不確定這一點,那麼無論您需要專門std::swap或你需要禁止你的課程的用戶使用它。]

由於你的類在其析構函數中什麼都不做,所以任何一個選項都可以。選項2對於用戶來說可能更容易處理,但是如果他們在假定他們不能用移動對象做任何事情的情況下進行編碼,那麼再一次沒有區別。因爲這個類是不完整的,但是當你編寫析構函數時,這個類可能會改變。

+0

謝謝:對我來說,「關鍵」信息是可以調用析構函數來移動object_。所以如果'File'包裝器管理'FILE *',那麼'other.m_fp'必須用'nullptr'清除,以避免多次關閉同一個'FILE *'。 –

+0

+1。但是,我記得在稍後的一篇類似的文章中說了一些棒。我認爲,這個標準並不總是要求事物具有可破壞性。我想這是源於標準嚴格要求和大多數日常情況下明智的要求之間的區別。 – juanchopanza

+0

@juanchopanza:是的,我想如果你對這種類型的有效用途進行了足夠的對衝,你可以安排一個移動的對象不能在用戶沒有做任何事情以使其安全的情況下銷燬。實際上你不得不禁止臨時建築和類似建築,因爲用戶在實際銷燬之前沒有機會使其安全。正如你所說,它是符合規範的代碼,但要麼忽略了這一點,要麼就是*非常*特殊用途。 –

6

已從移動的物體仍然是一個對象,並且它必須在有效狀態,儘管它可能是不確定的。特別是,應該有可能安全地賦予一個新的值(當然,它必須是可破壞的,正如@Steve所說的那樣)。只要移出的對象保持有效,您想要爲您的課程提供什麼特定的語義就取決於您。

一般來說,您應該將「移動」視爲優化的「複製」。然而,對於某些類別在­ trin ­這樣的「僅移動」(例如unique_ptr),額外的保證可能是合適的–例如unique_ptr承諾在它被移動之後 - 它是空的,並且確實沒有別的東西說得通。

(您的實際代碼是不完整的,但考慮到一FILE*是唯纔是舉,資源排序的,它可能打破,你應該嘗試儘可能地–甚至use it directly模擬unique_ptr。)