2015-05-22 70 views
0

我有一個unique_ptr的簡化示例。我想知道在獨特指針中需要移動構造函數和移動賦值操作符嗎? 如果我理解移動構造函數(並傳遞右值),這兩行代碼應該相同。什麼是需要在Unique Pointers中移動構造函數和移動賦值構造函數?

UniquePointer<T> a(new T); 
UniquePointer<T> a(UniquePointer<T>(new T)); 

這裏是簡化UniquePointer代碼:

template<typename T> class UniquePointer { 
    T* m_ptr; 
public: 
    UniquePointer(const UniquePointer&) = delete; 
    UniquePointer& operator=(const UniquePointer&) = delete; 
    UniquePointer(UniquePointer&& rhs); 
    UniquePointer& operator=(UniquePointer&& rhs); 
    UniquePointer(T* ptr) : m_ptr(ptr) { } 
    T* operator->() const { return m_ptr; } 
    T& operator*() const { return *m_ptr; } 
    T* get() const { return m_ptr; } 
    ~UniquePointer() { delete m_ptr; } 
}; 
+0

回訪所有權:汽車獨特=的std :: make_unique () –

+1

不支持移動語義,你不能把它的向量 – sp2danny

回答

3

首先調用構造函數定期UniquePointer(T* ptr)(不是移動構造函數)。第二次調用移動構造函數UniquePointer(UniquePointer&& rhs),因爲您傳入類型爲UniquePointer的右值,並且複製構造函數被刪除。

你需要移動的構造也當你做

UniquePtr<T> ptr = std::move(some_old_unique_ptr); 

在這種情況下,你就從了一個需要std::move,因爲舊的一個是lvalue。在已構建的對象上調用移動賦值運算符

ptr = std::move(yet_another_ptr); // invokes the move assignment operator 

至於爲什麼您需要它們,這是因爲設計原因。這些對象是不可複製的,所以你需要移動它們。

+0

如果我理解你的權利它需要支持非標準的移動操作庫std:move()並沒有其他優點? – maniac

+0

@maniac你必須明白移動語義是什麼意思。它允許你「竊取」右側的資源,並且在處理複製對象的「昂貴」時非常有用。在某些情況下,您想防止複製(例如'unique_ptr'),所以移動是唯一的選擇。是的,在這種情況下,您需要移動構造函數和移動賦值運算符,否則將無法傳遞您的對象。注意:'std :: move'只對右值執行轉換,不會移動任何東西。 – vsoftco

0

std::unique_ptr需要移動構造函數和移動賦值運算符,因爲它是不可複製的因此唯一的對象。由於它是不可複製的,因此需要將它傳遞給事物,並由此將操作轉移到此處。

2

如果您需要將所有權從一個範圍轉移到另一個範圍,則需要單獨的對象。由於你不能(也不想)複製unique_ptr,這意味着你需要移動它。例如,從函數返回unique_ptr時。

std::unique_ptr<Foo> func() 
{ 
    std::unique_ptr<Foo> ptr(new Foo); 
    ... 
    return ptr; 
} 

這需要移動構造函數或複製構造函數。另一個常見用例是從構造函數參數中初始化一個類成員。

class Widget 
{ 
public: 
    Widget(std::unique_ptr<Foo> _foo_ptr) 
     :foo_ptr(std::move(_foo_ptr)) 
    {} 
private: 
    std::unique_ptr<Foo> foo_ptr; 
};