2014-05-06 13 views
18

ho tale problema: io ho classe Foo, e se hanno alcuni oggetti di questa classe, std :: vector di riferimenti

Foo a(); 

ho bisogno di mettere questo oggetto per 2 diversi vettori:

std::vector<Foo> vA, vB; 

e se a cambiamenti vA dovrebbe essere cambiato in vB, vettori vA e vB possono essere diversi, ma possono h sono gli stessi oggetti. So che è possibile farlo con Boost, ma non posso usare Boost.

+3

Forse cercavi da usare [ 'std :: vector >'] (http://en.cppreference.com/w/cpp/memory/shared_ptr)? –

+4

Si noti che una dichiarazione come 'Foo a();' non fa ciò che si pensa che faccia. In realtà è una dichiarazione di una funzione 'a' che non accetta argomenti e restituisce un oggetto' Foo'. –

+3

Non sono sicuro se ciò che 'Foo a()' è * supposto * significhi, ma dichiara una funzione chiamata 'a' che restituisce un' Foo'. –

risposta

39

Ci sono alcune possibilità:

  1. Conservare un vettore di puntatori (l'uso, se i vettori azionariato del puntatori):

    std::vector<std::shared_ptr<Foo>> vA, vB; 
    
  2. Conservare un vettore di riferimenti avvolte (uso se i vettori non condividono la proprietà dei puntatori, e si sa l'oggetto fa riferimento sono validi oltre la durata dei vettori):

    std::vector<std::reference_wrapper<Foo>> vA, vB; 
    
  3. Conservare un vettore di puntatori prime (utilizzare se i vettori non condividono la proprietà dei puntatori, e/o puntatori memorizzati possono cambiare a seconda di altri fattori):

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

    Questo è comune per l'osservazione, tenere traccia delle allocazioni, ecc. Si applicano i normali avvertimenti per i puntatori grezzi: Non utilizzare i puntatori per accedere agli oggetti dopo la fine della loro durata.

  4. Conservare un vettore di std::unique_ptr che avvolgono gli oggetti (utilizzare se i vettori vogliono passaggio della proprietà dei puntatori nel qual caso la durata degli oggetti a cui fa riferimento sono disciplinati dalle regole del std::unique_ptr classe):

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

Il commento su non usare 'shared_ptr' a meno che in condizioni estreme sia solo sbagliato. Se i puntatori sono per la navigazione (il caso più frequente), non dovresti usare 'shared_ptr'. –

+0

Nell'esempio dell'OP, sembra intendere che i suoi oggetti siano allocati nello stack, quindi sono d'accordo con @JamesKanze in quanto il suggerimento del puntatore intelligente fortemente formulato è inappropriato e potenzialmente fuorviante. – JBentley

+0

@JamesKanze, grazie - Ho aggiornato il mio post. – utnapistim

2

Invece di mantenere Foo come oggetto mantenere come puntatore all'oggetto Foo, ad es.

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

e gestire le allocazioni e deallocazioni attentamente per evitare perdita di memoria (Allocare ma non deallocando quando fatto). Se si assegna un oggetto Foo e si mantiene il puntatore sia in vA che in vB, allora si mantiene essenzialmente lo stesso oggetto sia attraverso il puntatore. Altrimenti si può usare puntatore intelligente (meglio) riferiscono:

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

+0

Immagino che le persone siano downvoting perché ci sono opzioni che non richiedono manualmente (erroneamente) la gestione di quei puntatori (puntatori intelligenti come 'shared_prt') che sarebbero più appropriati. – Mat

+0

@Mat: Soprattutto la parola * attentamente * sapendo che tutti noi abbiamo un brutto giorno o due. –

+0

hai ragione, ci sono due opzioni, usa un puntatore gestito o gestisci il tuo puntatore a seconda dell'esperienza. –

7

Hai bisogno di un vettore di riferimenti. E poiché si specifica che è necessario utilizzare std :: vector, la cosa corretta da fare è racchiudere gli oggetti nello std::reference_wrapper.This page from C++ reference dovrebbe spiegarlo bene:

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

Ciò rende impossibile (credo) modificare qualsiasi puntatore (che è una caratteristica o un difetto, a seconda di cosa si sta facendo con 'vector'). –

+0

L'unico requisito dall'OP è quello di memorizzare i riferimenti all'oggetto Foo, quindi non ci sono puntatori qui per essere in grado di cambiare. Il programmatore è libero di modificare il contenuto di un vettore e di uno qualsiasi degli attributi della variabile 'a' in qualsiasi momento. Il riferimento stesso è, per definizione, immutabile. – alpartis