2014-05-06 21 views
18

Mam taki problem: Mam klasę Foo, a jeśli jakieś obiekty tej klasy, std :: vector odniesień

Foo a(); 

muszę umieścić ten obiekt do 2 różnych wektorów:

std::vector<Foo> vA, vB; 

a jeśli a zmiany vA powinna ona zostać zmieniona w vB, wektory vA i vB mogą być różne, ale mogą one h ave same obiekty. Wiem, że można to zrobić dzięki Boost, ale nie mogę użyć Boost.

+3

Czy chodziło Ci używać [ 'std :: vector >'] (http://en.cppreference.com/w/cpp/memory/shared_ptr)? –

+4

Należy zauważyć, że deklaracja typu 'Foo a();' nie robi tego, co myślisz, że robi. Jest to deklaracja funkcji 'a', która nie przyjmuje argumentów i zwraca obiekt' Foo'. –

+3

Nie wiem, czy to, co 'Foo a()' ma * na myśli *, ale deklaruje funkcję zwaną 'a' zwracającą' Foo'. –

Odpowiedz

39

Istnieje kilka możliwości:

  1. Przechowuj wektor wskaźników (wykorzystanie jeśli wektory własności akcji z wskaźniki):

    std::vector<std::shared_ptr<Foo>> vA, vB; 
    
  2. Store wektorem owiniętych odniesienia (użycie jeśli wektory nie podzielają własności ze wskaźników, a wiesz, że obiekt odwołuje ważnej przeszłości życia wektorów):

    std::vector<std::reference_wrapper<Foo>> vA, vB; 
    
  3. przechowywać wektor surowych wskaźników (użyj jeśli wektory nie podzielają własność wskaźników i/lub wskaźniki zawarte mogą ulec zmianie w zależności od innych czynników):

    std::vector<Foo*> vA, vB; 
    

    Jest to typowe dla obserwacji, śledzenia przydziałów itp. Obowiązują zwykłe zastrzeżenia dotyczące surowych wskaźników: Nie należy używać wskaźników, aby uzyskać dostęp do obiektów po upływie ich czasu życia.

  4. Store wektorem std::unique_ptr że owinąć obiekty (użyj jeśli wektory chcą przekazania własności tych wskaźników w przypadku których żywotność przywoływanych obiektów są regulowane przez przepisy std::unique_ptr klasa):

    std::vector<std::unique_ptr<Foo>> vA, vB; 
    
+1

Komentarz dotyczący niestosowania 'shared_ptr', chyba że w ekstremalnych warunkach jest po prostu nieprawidłowy. Jeśli wskaźniki służą do nawigacji (najczęstszy przypadek), _nie_ używaj 'shared_ptr'. –

+0

W przykładzie OP zdaje się, że jego obiekty są przydzielane na stosie, więc zgadzam się z @JamesKanze, że twoja silnie sformułowana sugestia inteligentnego wskaźnika jest niewłaściwa i potencjalnie wprowadzająca w błąd. – JBentley

+0

@JamesKanze, dzięki - zaktualizowałem swój post. – utnapistim

2

Zamiast utrzymywać Foo jako obiekt jako wskaźnik do obiektu Foo, np.

std::vector<Foo *> vA, vB; 

i zarządzać przydziały i deallocations ostrożnie, aby uniknąć wycieku pamięci (Przydzielanie ale nie dealokując kiedy zrobione). Jeśli przydzielisz jeden obiekt Foo i utrzymasz wskaźnik zarówno w vA, jak i vB, to zachowujesz w zasadzie ten sam obiekt zarówno przez wskaźnik. W przeciwnym wypadku można użyć inteligentnego wskaźnika (lepiej) patrz:

What is a smart pointer and when should I use one?

+0

Zgaduję, że ludzie tracą ważność, ponieważ istnieją opcje, które nie wymagają ręcznego (niewłaściwego) zarządzania tymi wskaźnikami (inteligentne wskaźniki, takie jak "shared_prt"), które byłyby bardziej odpowiednie. – Mat

+0

@Mat: Zwłaszcza słowo * ostrożnie * wiedząc, że wszyscy mamy zły dzień lub dwa. –

+0

masz rację, są dwie opcje, użyj zarządzanego wskaźnika lub zarządzaj własnym wskaźnikiem w zależności od wiedzy. –

7

Potrzebny jest wektor referencje. A ponieważ określasz, że musisz użyć std :: vector, poprawne jest wykonanie obiektów w std::reference_wrapper.This page from C++ reference powinien to wyjaśnić ładnie:

vector<reference_wrapper<Foo>> vA, vB; 
vA.push_back(a); 
vB.push_back(a); // puts 'a' into both vectors 

// make changes to 'a' 
// use .get() to get the referenced object in the elements of your vector 
// vA[0].get() == vB[0].get() 
+0

Uniemożliwia to (jak sądzę) zmianę dowolnego ze wskaźników (który jest albo funkcją, albo defektem, w zależności od tego, co robisz z "wektorem"). –

+0

Jedynym wymaganiem z OP jest przechowywanie odniesień do obiektu Foo, więc nie ma tutaj żadnych wskazówek, które można by zmienić. Programista może dowolnie zmieniać zawartość wektora i dowolnych atrybutów zmiennej "a". Samo odniesienie jest, z definicji, niezmienne. – alpartis

Powiązane problemy