2012-01-24 19 views
6

Chciałbym mieć wektor unique_ptr jako członka klasy, którą tworzę.Jak zadeklarować wektor unique_ptr jako członka danych klasy?

class Foo { 
    [...] 

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

Ale potem zaczynają się tajemnicze komunikaty o błędach z VS2010 kompilatora:

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

Wraz z kilkoma liniami błąd poniżej tego, co nurkować w realizacji Microsoftu std::_Copy_impl<> ...

Zmieniłem deklarację członka na

vector<unique_ptr<Bar>>* barList; 

I to kompiluje. Ale nie mogę przestać się zastanawiać, dlaczego nie mogę tego zrobić tak, jak pierwotnie chciałem? Dla uśmiechami, próbowałem to i to działa dobrze:

vector<Bar> barList; 

Ale teraz tracę wygodę unique_ptr. Chcę moje ciasto i ja też chcę je zjeść!

+0

Patrzyłem na http://stackoverflow.com/questions/8553464/vector-as-a-class-member i odpowiedź wydaje się myśleć, że deklarowanie "wektora", tak jak ja, jest po prostu w porządku. Z jakiegoś powodu wydaje się powodować nielegalne kopie podczas dodawania części 'unique_ptr'. –

+1

Jak wygląda twój konstruktor kopiowania i operator przypisania? –

+0

Prywatne zadanie, ale konstruktor kopii był winowajcą. Przełączono z 'unique_ptr' na' shared_ptr', gdy zdałem sobie sprawę, że używam niewłaściwego semantycznego własności. –

Odpowiedz

10

Problem polega na tym, że gdzieś twój kod próbuje wywołać operatora "przypisania kopiowania" Foo.

Powoduje to, że kompilator próbuje wygenerować operację kopiowania, która wywołuje operatorów przydziału kopiowania wszystkich podobiektów Foo. Ostatecznie prowadzi to do próby skopiowania unique_ptr, operacji, która nie jest możliwa.

+0

Dzięki za wskazanie tego. Kompilator wprowadzał mnie w błąd, ponieważ błąd odwoływał się do deklaracji członkowskiej i nie wspomniał o kolidującym kodzie powodującym kopię. Wyobrażam sobie, że jest to niedobór VS2010 i mam nadzieję, że poprawi się w nowszych wersjach. Moja klasa 'Foo' ma konstruktor kopiowania, a ja próbowałem skopiować wektor ze źródła' Foo'. Współdzielona własność wydaje się lepszym rozwiązaniem, więc zmiana na 'shared_ptr' rozwiązała problem. –

+1

Wygląda na błąd w VS2010. Otrzymuję ten błąd, nawet jeśli mój kod nigdy nie próbuje wywołać funkcji copy-assigment. Wyłączenie operatora = z deklarowaniem jako prywatnym (stąd = usuwanie nie jest obsługiwane) rozwiązuje problem. – tr3w

-2

Nie można użyć unique_ptr w wektorze, ponieważ implementacja wektora silnie opiera się na operatorze przypisania wartości, który jest prywatny w unique_ptr. Użyj shared_ptr z boost lub innej implementacji smart ptr z C++ 11.

+6

'unique_ptr' działa dobrze w" wektorze ". [Zobacz.] (Http://ideone.com/riLhp) –

+0

Kontenery C++ 11 są wymagane do pracy z typami typu "tylko ruch", takimi jak 'unique_ptr'. – bames53

+0

Miałem na myśli sposób, w jaki go użył. Ale nadal, dziękuję, nie wiedziałem o emplace_back. – aambrozkiewicz

4

unique_ptr nie ma semantyki kopiowania, więc nie można użyć żadnych metod, które skopiowałyby dany obiekt. Możesz może zrobić to z odwołaniami rvalue za pomocą std::move w miejscu (miejscach), które próbuje zrobić kopię. Nie widząc twojego kodu, nie mogę powiedzieć, gdzie by to było.

Jeśli kompiluje się w drugiej formie, nie używałeś tego samego kodu lub wystąpił błąd kompilatora. Oba powinny zawodzić w ten sam sposób.

Twój trzeci przykład, przechowywanie według wartości, jest najprostszym sposobem, o ile twoje obiekty nie są duże i drogie do przechowywania/kopiowania według wartości.

+1

'auto_ptr' to ten, który nie przestrzega normalnej semantyki kopiowania,' unique_ptr' po prostu nie ** ma ** kopię semantyki – Grizzly

+0

Twoje odpowiedzi i Mankara są bardzo podobne. Jego jednak uświadomił mi, że muszę polować na czarownice, aby złamać kod (odpowiedź na to pytanie była bardziej subtelna). Oboje jednak zasługują na zaakceptowaną odpowiedź. Dzięki za pomoc! –

2

Często gdzieś brakuje elementu std::move(iUniquePtr) (np. Przy użyciu funkcji push_back).

0

An fragmenty www.cplusplus.com

std::unique_ptr::operator= 

unique_ptr przypisanie Przedmiotem nabywa własność zawartości X, w tym zarówno przechowywanego wskaźnika i przechowywane Deleter (wraz z odpowiedzialnością usunięcie obiektu w pewnym momencie). Każdy obiekt należący do obiektu unique_ptr przed wywołaniem jest usuwany (tak jakby wywołano destruktor unique_ptr).

Ale jest też ostrzeżenie:

Ta strona opisuje funkcja wprowadzona przez najnowszej wersji standardu C++ (2011). Starsze kompilatory mogą go nie obsługiwać.

MSVC 2010 definiuje operator= jako prywatny (nie do kopiowania), ale obsługuje metodę swap.

Powiązane problemy