2012-01-24 75 views
6

我想有一個unique_ptr的向量作爲我正在創建的類的成員。如何將unique_ptr的向量聲明爲類數據成員?

class Foo { 
    [...] 

private: 
    vector<unique_ptr<Bar>> barList; 
} 

但後來我開始從VS2010編譯器越來越神祕的錯誤消息:

error C2248: 'std::unique_ptr<_Ty>::operator =' : cannot access private member declared in class 'std::unique_ptr<_Ty>' 

隨着低於誤差線的那一疊潛入微軟的落實std::_Copy_impl<> ...

我將會員聲明更改爲

vector<unique_ptr<Bar>>* barList; 

它編譯。但我不禁想知道爲什麼我不能像我最初想要的那樣去做?對於笑容,我想這和它的作品罰款:

vector<Bar> barList; 

但現在我失去了unique_ptr便利。我想要我的蛋糕,我也想吃!

+0

我在看http://stackoverflow.com/questions/8553464/vector-as-a-class-member,答案似乎認爲像我這樣聲明一個'vector'就好了。但出於某種原因,在添加'unique_ptr'部分時似乎會觸發非法副本。 –

+1

你的副本構造函數和賦值運算符是什麼樣的? –

+0

私人轉讓,但複製構造是罪魁禍首。當我意識到我在使用錯誤的所有權語義時,從'unique_ptr'切換到'shared_ptr'。 –

回答

10

這裏的問題是,在某處,您的代碼嘗試調用Foo的「複製分配」操作符。

這會導致編譯器嘗試生成調用Foo所有子對象的複製賦值運算符的複製賦值運算符。最終,這導致嘗試複製unique_ptr,這是不可能的操作。

+0

感謝您指出這一點。編譯器誤導了我,因爲錯誤引用了成員聲明,​​並沒有提及引起副本的違規代碼。我想這是VS2010的一個缺陷,並且希望可以通過更新的版本進行改進。我的'Foo'類有一個拷貝構造函數,我試圖將這個向量從'Foo'中拷貝出來。共享所有權似乎是更好的解決方案,所以切換到'shared_ptr'完成了任務。 –

+1

它看起來像VS2010中的一個錯誤即使我的代碼永遠不會嘗試調用複製分配,我也會收到此錯誤。禁用operator =聲明爲private(因此=不支持delete)解決了這個問題。 – tr3w

-2

您不能在vector中使用unique_ptr,因爲矢量實現強烈依賴於賦值運算符,該賦值運算符在unique_ptr中是私有的。使用來自C++ 11的boost或其他智能ptr實現的shared_ptr

+6

'unique_ptr'在'vector'中運行得很好。 [見](http://ideone.com/riLhp) –

+0

C++需要11個容器來處理像unique_ptr這樣的移動類型。 – bames53

+0

我的意思是他用它的方式。但是,謝謝你,我不知道emplace_back。 – aambrozkiewicz

4

unique_ptr沒有複製語義,所以你不能使用任何方法來複制包含的對象。你可以做它與rvalue引用通過使用std::move它試圖做一個副本的地方。沒有看到你的代碼,我不能說這將是什麼。

如果它以第二種形式編譯,或者您沒有運行相同的代碼或者存在編譯器錯誤。兩者都應該以同樣的方式失敗。

第三個例子中,按值存儲是最簡單的方法,除非您的對象是大型且昂貴的按值存儲/複製。

+1

'auto_ptr'是一個不遵守正常的複製語義,'unique_ptr'根本不**具有**複製語義 – Grizzly

+0

你的和Mankarse的答案非常相似。不過,他讓我意識到我需要去尋找這個有問題的代碼(你的回答更加巧妙地解決了這個問題)。不過,你們都應該得到公認的答案。謝謝您的幫助! –

2

通常std::move(iUniquePtr)在某處丟失(例如使用push_back時)。

0

的節選從www.cplusplus.com

std::unique_ptr::operator= 

的unique_ptr分配 對象獲得的X的內容所有權,包括所存儲的指針和存儲的刪除器(與刪除對象的責任沿在某一點)。在調用被刪除之前,unique_ptr對象擁有的任何對象(就像調用unique_ptr的析構函數一樣)。

但是有一個警告過:

本頁面描述了由C++標準(2011年)的最新版本中引入的功能。較早的編譯器可能不支持它。

MSVC 2010將operator=定義爲私有(不可複製),但支持swap方法。

相關問題