2016-05-09 36 views
3

我有一個簡單的問題關於Box<X>。 我明白它的作用,它在堆上分配X。 在C++中,您使用新的運算符在堆上分配某些內容,以便它可以超出當前範圍(因爲如果您在堆棧上創建某些內容,它將在當前塊的末尾消失)。框<X> vs在X上移動語義

但是,閱讀Rust的文檔,它看起來像你可以在堆棧上創建一些東西,並仍然返回它利用語言的移動語義,而不必訴諸堆。 然後,我不清楚何時使用Box<X>而不僅僅是X

我剛開始閱讀關於鏽,所以我道歉,如果我失去了明顯的東西。

回答

6

首先: C++ 11(和更新的版本)具有右值引用的移動語義。所以你的問題也適用於C++。請記住,C++的移動語義 - 與Rust的不同 - 非常不安全。

第二個:單詞「移動語義」不知何故暗示沒有「複製」,這是不正確的。假設你有一個帶有100個64位整數的struct。如果你要通過移動語義傳遞這個結構的對象,那麼這100個整數將被複制(當然,編譯器的優化器通常可以刪除這些副本,但無論如何...)。移動語義的優勢在處理處理堆中某些數據的對象(或一般指針)時起作用。

例如,看看Vec(類似於C++的vector):類型本身只包含指針和兩個指針大小整數(ptrlencap)。當矢量移動時,這些三倍64位仍然被複制,但矢量(它位於堆上)的主要數據未被觸及。


話雖這麼說,讓我們討論的主要問題:「爲什麼使用Box在所有?」。實際上有許多用例:

  • 未施膠的類型:某些類型(例如性狀的對象還包括封閉件)的未施膠,意味着它們的尺寸是未知的給編譯器。但是編譯器必須知道每個堆棧幀的大小 - 因此那些未經處理的類型不能存在於堆棧中。
  • 遞歸數據結構:想到一個BinaryTreeNode結構。它節省了名爲「左」和「右」的兩個成員... BinaryTreeNode?這是行不通的。因此,您可以將兩個孩子都裝箱,以便編譯器知道結構的大小。
  • 巨大的結構:想到上面提到的100整數結構。如果你不想每次都複製它,你可以將它分配到堆上(這種情況很少出現)。
+0

是什麼讓C++移動特別不安全? – erip

+1

在Rust中,編譯器保證程序員不能訪問已被移動的對象,C++允許使用移動的對象。在特別糟糕的情況下,您可以訪問指向釋放的內存或其他無效數據的指針。 –

+0

這比C++中的其他任何東西都不安全。例如。在C++中,拷貝構造函數可能會拷貝一個原始指針,然後你會得到一個雙免費的。 C++只是希望你在這裏實現一個行爲正常的{copy,move}構造函數。 – mcarton

1

有些情況下,你不能返回X例如。如果X?Sized(特徵,非編譯時大小數組等)。在這些情況下,Box<X>仍然有效。