2015-07-28 16 views
3

通過在C++中引入std :: move,您可以擺脫不必要的副本。問題是,雖然可以將該值從一個變量中移出,但不能阻止該函數的其餘部分仍然引用該變量。如何防止在其值已被移動到另一個變量後使用變量?

例如,假設我調用返回一個大的載體功能,然後(在一些代碼)我想這個載體轉移到另一個變量,像這樣:

auto lotsOfBooks = getAllBooks(); 
if (lotsOfBooks.empty()) 
    return; 
... 
auto library = Library("National Library", std::move(lotsOfBooks)); 

的舉動後,將書容器添加到庫中,我不希望代碼的其餘部分再引用lotsOfBooks變量。但我沒有看到防止這種情況的方法。

我知道在很多情況下,您可以簡單地將函數的一部分放在它自己的嵌套塊中(將它們放在花括號中),但這並非總是可行。 在這種情況下,可以通過使用std::unique_ptr<Library>而不是Library來規避問題,但內存分配並不總是需要的。

有沒有辦法在特定的語句/行後面使用變量(使用編譯器構造,C++構造,代碼檢查工具(如Lint),...)?

+0

有時候,在'lotsOfBooks = getInterestingBooks();'時候引用'lotsOfBooks'是有意義的。也就是說,你可以在移動後#define lotsOfBooks'並在範圍末尾使用'#undef lotsOfBooks'。如果您每次都可以捕獲移動變量的意外使用,那麼您就可以這樣做。 – nwp

+0

'lotsOfBooks'是一個有效的可破壞對象,如果執行得當,它必須允許你使用任何沒有先決條件的方法。例如,這通常包括分配。所以你可以保留它只是爲了分配別的東西。 –

回答

1

你永遠無法阻止程序員在代碼中的某處寫出錯誤的句子。你可以(在編譯器的幫助下)是:

  • 嘗試檢測最常見的錯誤
  • 做你最適合這樣的錯誤被檢測爲在運行時SOOS地(至少在調試非優化模式)

這就是在C++ 11中移動的情況。原始指針設置爲空,或者原始容器被清空。它提供了2個漂亮的後果:

  • 析構函數不能破壞任何東西(刪除一個空指針是無害的,所以是一個空的容器的破壞)
  • 老變量的任何訪問應立即拋出一個異常:空指針訪問/分配,向量的索引超出範圍等。
1

正如你自己所建議的那樣,你只能通過將變量放入本地塊來限制變量的範圍。沒有其他方法來阻止訪問移動的變量。

相關問題