2017-01-06 34 views
4
// move constructor 
    ArrayWrapper (ArrayWrapper&& other) 
     : _p_vals(other._p_vals ) 
     , _size(other._size) 
    { 
     other._p_vals = NULL; 
     other._size = 0; 
    } 

我找到了右值引用的教程。我真的不明白,爲什麼我們要成立other._p_vals = NULL;other._size = 0; 作者解釋:C++中的右值引用

,但爲什麼我們需要設置other._p_vals = NULL?原因是 析構函數 - 當臨時對象超出範圍時,就像所有其他C++對象一樣,其析構函數將運行。

如果它走出去的範圍,也被打爛何苦設置other._p_vals = NULL

當它的析構函數運行, 它還將釋放_p_vals。我們剛剛複製的相同_p_vals!

我以爲我們感動沒有複製,或者我錯了嗎?

如果我們 不設置other._p_vals爲NULL,此舉不會真正成爲一個 舉動 - 這純粹是引入了後來崩潰,一旦我們 開始使用釋放的內存拷貝。這是整點移動 構造函數:通過改變原來的副本,臨時的 對象!

有人能幫我理解嗎?!?

+0

析構函數的代碼會對'_p_vals'做一些事情(例如'delete's it)。如果你沒有這些線條,那麼你實際上是在複製而不是在移動。 –

回答

4

因爲此類包含一個原始指針,我們只能假定它擁有它,因此它的析構函數必須像:

ArrayWrapper::~ArrayWrapper() { 
    delete[] _p_vals; 
} 

在這種移動構造函數,我們「偷」的other的內部。如果我們不清除other的內部(注意保持一致的「空」狀態,所以也設置_size = 0),那麼當other或新對象中的任何一個被銷燬時,剩下的將指向在一些已經被刪除的數據上。

共享內部結構與竊取其他內部組件的模式非常不同。

+0

但是,不是其他一個臨時的對象,無論如何將被銷燬嗎? – Samu

+2

不一定,但讓我們假設它是。然後'other'被銷燬,並且在其析構函數中(假設它被正確寫入),''刪除'_p_vals'。然後新對象指向垃圾。 – BoBTFish

+0

謝謝,現在有道理! – Samu