2014-10-11 371 views
20

C++11我們可以使用std::move()將對象的所有權轉讓給另一個unique_ptr。股權轉讓完成後,即割讓所有權的智能指針變爲nullget()返回nullptr.將對象的所有權從一個unique_ptr轉移到C++ 11中的另一個unique_ptr?

std::unique_ptr<int> p1(new int(42)); 
std::unique_ptr<int> p2 = std::move(p1); // Transfer ownership 

什麼在哪裏,因爲它是轉移所有權轉讓給其他unique_ptr這將是非常有用的情況呢?

+4

就是這樣。標準庫中的智能指針不應該被看作是自動釋放的指針,而是根據*所有權*。你有一些數據只能由一個實體「擁有」,然後使用唯一的指針。 – 2014-10-11 19:41:07

+4

當您使用線程或套接字等不可複製的數據進行工作時,並且您需要將其從一個位置替換爲另一個位置(例如,將其放入向量中),這非常有用。 – wowofbob 2014-10-11 19:59:55

回答

2

例如,如果你調用一個函數,你可以在參數列表moveunique_ptr因此它可以是你的函數簽名

foo (std::unique_ptr<T>&& ptr) 

的一部分,你可以調用foo與

foo(std::move(myPtr)); 

std::move是無條件轉換,unique_ptr是具有狀態的對象,並且該狀態的一部分是unique_ptr管理的指針,其中std::move荷蘭國際集團整個對象,你是不是真的改變了人們擁有什麼,沒有什麼特別之處std::unique_ptr同時使用std::move因爲std::move並不真正關心什麼具體的,我說這是一個無條件的演員和unique_ptr簡單地被澆鑄成型,整個作爲unique_ptr<T>類型實例的對象被鑄造。

如果您想談談您的unique_ptr指出的對象的所有權轉讓,您應該考慮std::unique_ptr<T>本身提供的swap

+1

當您將'move'移動到另一個'unique_ptr'時,'unique_ptr'傳輸管理對象的所有權。 – 2014-10-12 00:43:22

+0

@JonathanPotter在語義上是不正確的,'move'什麼也不做,只是一個強制轉換,其語義是關於將表達式變爲右值,而不是在'unique_ptr'的情況下轉移所有權,當函數調用將會發生,那'unique_ptr'將被移動,這是一個副作用,如果你的目的是改變所有權這是用錯誤的語義做這件事最神祕的方式,只是不這樣做,使用'swap',它具有正確的語義,它只是做你想做的。 – user2485710 2014-10-12 06:58:36

+0

說實話,我不太清楚你的意思。但是,如果使用'move'將'unique_ptr' push_back到'vector'中,你會怎麼想呢? – 2014-10-12 07:35:41

19

以下情形涉及從一個unique_ptr轉移到另一個所有權:從函數返回,並作爲參數傳遞給像一個構造函數。

說你有一些多態型Animal

struct Animal { 
    virtual ~Animal() {} 
    virtual void speak() = 0; 
}; 

與具體子類CatDog

struct Cat : Animal { 
    void speak() override { std::cout << "Meow!\n"; } 
}; 

struct Dog : Animal { 
    void speak() override { std::cout << "Woof!\n"; } 
}; 

你想要一個簡單的工廠,創建基於服從的要求值的寵物。然後工廠必須返回一個指針。我們希望寵物工廠創建寵物的所有權轉移給調用者這樣一個合理的返回類型爲std::unique_ptr<Animal>

std::unique_ptr<Animal> createPet(double obedience) { 
    if (obedience > 5.0) 
    return std::make_unique<Dog>(); 
    return std::make_unique<Cat>(); 
} 

現在,假設我們要創建一個House將擁有的寵物那麼我們可能會想傳遞寵物進入House的構造函數。還有一些爭議(see comments on this blog post)關於如何最好的unique_ptr傳遞給構造函數,但它會是這個樣子:

class House { 
private: 
    std::unique_ptr<Animal> pet_; 
public: 
    House(std::unique_ptr<Animal> pet) : pet_(std::move(pet)) {} 
}; 

我們已通過了unique_ptr到構造,並再「移動」,它給成員變量。

調用代碼可能看起來是這樣的:

auto pet = createPet(6.0); 
    House house(std::move(pet)); 

構建House後,pet變量會nullptr因爲我們已經轉移了寵物所有權有關的House

Live demo

+0

更改構造函數以獲取unique_ptr的r值引用會更好嗎?例如。 House(std :: unique_ptr && pet)。那麼你不需要在pet_的初始化列表中使用std :: move()調用? – jfritz42 2016-11-16 00:15:21

+1

@ jfritz42一個r值引用本身就是一個l值,所以你仍然需要'std :: move'。 [試試](http://coliru.stacked-crooked.com/a/42b8222989a16651)。 – 2016-11-16 07:49:25

+0

好點!順便說一句,這似乎是一個新的C++習慣用法。我想知道是否有任何人給出了一個名字。 「轉讓所有權成語」? – jfritz42 2016-11-16 19:25:24

相關問題