2016-08-18 83 views
0

我無法理解C++移動語義。假設我想從一個方法返回一個大對象。爲了使這個操作更高效,我使用大對象類的移動構造函數。我調用一個方法來獲取一個大對象並將其傳遞給另一個將處理它的方法。移動構造函數是如何工作的?

processLargeObject(getLargeObject()); 

餘寫方法getLargeObject()其中創建一個較大的對象。如果我創建的對象沒有新的操作符,我可以理解存儲是分配在堆棧上的。在我事先知道對象的大小並將其表示爲數組的情況下,可將此大對象定義爲double foo[1000000000];。現在移動構造函數裏面,如果我說

foo = other.foo; 

那麼移動的對象仍然會駐留在堆棧和堆棧擴展可以被覆蓋。

所以這不能是如何使用移動構造函數。移動構造函數只能用於移動堆中的物體嗎?

+0

'foo = other.foo;'如果'foo'是一個雙精度數組,則不會編譯。無論如何,你會如何移動一組普通的雙打? – Praetorian

+0

這是否意味着我必須遍歷數組並創建副本? – AggieMan

+0

您是否嘗試過聲明並使用一個在其中包含十億個雙精度數組的對象?看起來像是溢出堆棧的好方法。你應該使用'vector '然後移動實際上是有意義的。 – Praetorian

回答

2

移動構造函數是如何工作的?

一招構造應該做一個副本 - 而不是一個複製拷貝構造函數應該做的。除了進行淺拷貝之外,移動構造函數還「竊取」由移出的對象指向的任何資源(例如外部內存緩衝區,例如std::vector擁有的緩衝區)。

爲了使這個操作高效,我使用大對象類的移動構造函數。

從迂迴的角度來說,對象本身的大小並不會使得移動比複製更高效。當對象指向可能被「盜取」的某些大型資源時,此舉很有效。如果你的意思是說這樣的外部資源是使對象「大」的話,那麼就足夠公平了。

移動構造函數只能用於移動堆中的物體嗎?

無論存儲對象的位置 - 無論是自動,動態還是靜態,都可以從中移動。只要類型是可移動的。

這個大對象可以被定義爲double foo[1000000000];

這是一個非常大的物體,不指向可能被竊取任何外部資源的一個很好的例子。移動一個雙精度數組與複製它完全一樣。

+0

謝謝。我得到了這部分。我不明白的是,移動的對象是否需要駐留在堆上? – AggieMan

+0

@AggieMan看到編輯。 – user2079303

+0

爲了使移動構造函數具有顯着的優勢,大多數數據應該存儲在對象中指針引用的堆上的數據中。 (所以,一個'std :: array '通常與移動構造一樣昂貴,但是具有1000000個元素的'std :: vector '對於移動構造來說非常快。 ) –