2014-05-18 136 views
2

我一直在研究std :: unique_ptr,但在某些時候對它的語義感到困惑。從documentationstd :: unique_ptr的唯一性

No two unique_ptr instances can manage the same object 

但是,即使辛苦也很可能是一個愚蠢的例子,考慮這樣的代碼。

std::unique_ptr<int> a(new int(10)); 
std::unique_ptr<int> b = std::unique_ptr<int>(a.get()); 
std::cout << *b << std::endl; 
*a = 5; 
std::cout << *b; 

a和b是在這裏管理同一個對象,輸出爲10 5.當然,我在調試模式得到一個斷言失敗錯誤在最後由於兩個獨特的師生比試圖銷燬同一對象在範圍的最後。

我知道這很愚蠢,並不建議這樣使用,但是當它不是很明顯的時候我會遇到這種情況(一個類的成員調用另一個類等),而斷言失敗是我開始使用的。

我的問題是上述語句的意思:它是由標準和一個體面的編譯器構成的,它不應該允許你這樣做(我在vs2013 btw上)或者你必須這樣做(永遠不會導致兩個unique_ptrs點)(不太可能,因爲unique_ptrs的目的是爲了讓我們不那麼擔心。)或者當涉及unique_ptr時,我不應該使用任何關於原始指針(a.get())的東西。

回答

2

你最後一句話是正確的。只要你在下面的行中使用a.get()的原始指針,你就拋棄了所有的std::unique_ptr對你的承諾。

std::unique_ptr<int> b = std::unique_ptr<int>(a.get()); 

正確的語義保持唯一性,而轉換爲原始指針是使用a.release()

std::unique_ptr<int> b = std::unique_ptr<int>(a.release()); 

當然,你通常只使用與std::move轉讓或initializatoin如果兩個std::unique_pointer實例之間,移動所有權由documentation給出。下面兩行中的任何一行都應該是有效的。

std::unique_ptr<int> b(std::move(a)); 
std::unique_ptr<int> b = std::move(a); 

爲了使std::move語義更清晰,請考慮以下測試程序。

#include <stdio.h> 
#include <memory> 
#include <stdlib.h> 


int main(){ 
    std::unique_ptr<int> a(new int(10)); 
    printf("%p\n", a.get()); 
    std::unique_ptr<int> b(std::move(a)); 
    printf("%p\n", a.get()); 
    printf("%p\n", b.get()); 
} 

在我的系統上,輸出如下。注意第一行和最後一行匹配。

0x1827010 
(nil) 
0x1827010 
+0

您需要使用'std :: unique_ptr b = std :: move(a);'。您必須對'std :: unique_ptr'使用移動賦值。 – ECrownofFire

+0

@ECrownofFire,修復,謝謝...我應該檢查。 – merlin2011

+0

我很難理解move semantcis。據我所知,這條線會使b指向a所指向的任何東西,並指向null,對嗎? – bahti