2017-05-08 88 views
5

我的做法是:如何將所有權從原始指針正確移動到std :: unique_ptr?

class SomeClass 
{ 
    std::vector<std::unique_ptr<MyObject>> myObjects; 
public: 
    void takeOwnership(MyObject *nowItsReallyMyObject) 
    { 
     myObjects.emplace_back(std::move(nowItsReallyMyObject)); 
    } 
}; 

上午我在做正確的一切還是有什麼更好的辦法呢?

+0

你不需要'std :: move'。 – juanchopanza

+0

在基元類型(指針)上調用'std :: move'沒有意義。 –

回答

4

move是冗餘的。

我自己,我應該這樣做:

void takeOwnership(std::unique_ptr<MyObject> nowItsReallyMyObject) 
{ 
    myObjects.emplace_back(std::move(nowItsReallyMyObject)); 
} 

因爲我想移動unique_ptr所有權語義據「走出去」成爲可能。

我可能會這樣寫效用函數:

template<class T> 
std::unique_ptr<T> wrap_in_unique(T* t) { 
    return std::unique_ptr<T>(t); 
} 

所以呼叫者可以:

foo.takeOwnership(wrap_in_unique(some_ptr)); 

但更重要的,則可以推unique_ptr語義走出國界,只要它們能合理。

我可能連做:

template<class T> 
std::unique_ptr<T> wrap_in_unique(T*&& t) { 
    auto* tmp = t; 
    t = 0; 
    return std::unique_ptr<T>(tmp); 
} 
template<class T> 
std::unique_ptr<T> wrap_in_unique(std::unique_ptr<T> t) { 
    return std::move(t); 
} 

,它可以讓來電者轉變他們的T*unique_ptr更容易。它們的所有T* - >unique_ptr<T>現在包裝在一個std::move中,並將源指針設置爲零。

所以,如果他們有

struct I_am_legacy { 
    T* I_own_this = 0; 
    void GiveMyStuffTo(SomeClass& sc) { 
    sc.takeOwnership(wrap_in_unique(std::move(I_own_this))); 
    } 
}; 

的代碼可被轉換成:

struct I_am_legacy { 
    std::unique_ptr<T> I_own_this; 
    void GiveMyStuffTo(SomeClass& sc) { 
    sc.takeOwnership(wrap_in_unique(std::move(I_own_this))); 
    } 
}; 

,它仍然編譯和工作原理相同。 (與I_own_this的其他交互可能需要更改,但其中的一部分已經與unique_ptr兼容)。

2

你應該接受來自unique_ptr開始走:

class SomeClass 
{ 
    std::vector<std::unique_ptr<MyObject>> myObjects; 
public: 
    // tells the world you 0wNz this object 
    void takeOwnership(std::unique_ptr<MyObject> myObject) 
    { 
     myObjects.push_back(std::move(myObject)); 
    } 
}; 

這樣,你清楚你取得所有權,你也幫助其他程序員避免使用原始指針。

進一步閱讀:CppCoreGuidelines R.32

+0

謝謝。但我更感興趣的是[CppCoreGuidelines R.33](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#r33-take-a-unique_ptrwidget-parameter-to-express-that-a -function-reseats-thewidget)。我需要把ref作爲myObject,因爲我不想在函數返回後將它刪除。另外VS2013表示,如果我嘗試通過val傳遞它,該函數將被刪除。或者我錯了? – Oliort

+0

@Oliort函數返回後,它不會被刪除,因爲您將std :: move()放入vector的'std :: unique_ptr'中。在std :: move之後,參數版本成爲'nullptr' – Galik

相關問題