2011-11-20 17 views
12

È legale disporre di un vettore di riferimenti a oggetti, come il seguente?Vettori di riferimenti agli oggetti

vector<Agent&> seenAgents; 

Quale sarebbe per esempio essere popolato da alcuni, ma non tutti gli oggetti nella scena?

Possiedo un vettore di oggetti Agent, ma il vettore descritto sopra deve contenere riferimenti solo a quelli attualmente visibili da ciascun agente, ovvero i riferimenti verranno aggiunti e rimossi in ogni momento.

È questo qualcosa che il linguaggio consentirà? E inoltre, c'è qualcos'altro di cui ho bisogno di essere a conoscenza? Se rimuovo un riferimento dal vettore, persiste ovunque? È una perdita di memoria?

mi sembra di essere sempre questo errore sulla linea di dichiarare il vettore:

error C2528: 'pointer' : pointer to reference is illegal 

è questo qualcosa a che fare direttamente con la linea o è molto probabilmente avvenendo da qualche altra parte? E 'in fase di inizializzazione dei costruttori initialiser lista come questa:

seenAgents(vector<Agents&>()) 
+0

Duplicato di http://stackoverflow.com/questions/922360/why-cant-i-make-a-vector-of-references –

risposta

19

Non si può avere vector di riferimenti, come un riferimento non è copiabile cedibile e tutti contenitori STL si suppone per memorizzare copiabile assegnabile elementi.

Ma è possibile rendere il contenitore per contenere puntatori. Mi piace:

vector< Agents* > seenAgents; 

Questo è un po 'pericoloso. Devi essere sicuro che questi suggerimenti rimarranno validi. Voglio dire - se qualcuno cancella un oggetto, puntato da un puntatore in questo contenitore, il puntatore diventa non valido. È necessario essere sicuri che ciò non accada, perché non è possibile verificarlo (non è possibile verificare per NULL, perché un puntatore non diventerà NULL, se qualcuno elimina l'oggetto puntato).

La soluzione migliore qui (fornita dal contenitore con i puntatori) sarebbe quella di utilizzare alcuni puntatori intelligenti, alcuni con il conteggio dei riferimenti, ad esempio; ti garantiranno che l'oggetto esisterà e che il puntatore è valido. E nel caso in cui l'oggetto, puntato dal puntatore intelligente, venga distrutto, è possibile verificarlo per NULL.

+2

Sei sicuro che i riferimenti non sono copiabili? Avrei pensato che non fossero assegnabili. – UncleBens

+0

Giusto, grazie. Ma non è ancora possibile "copiare" un riferimento, in quanto non è un tipo reale, non esiste realmente, voglio dire - non viene assegnato alcun momory (nella maggior parte delle implementazioni del compilatore, piuttosto sicuro - tutti). Ma ancora - sì, 'assegnabile 'suona più giusto e meno confuso. Modificato :) –

+0

Non è possibile anche costruirli di default. –

8

Non puoi farlo. Utilizzare i puntatori.

La biblioteca fornisce BoostPTR_VECTOR che è una soluzione migliore rispetto:

vector<T*> foo; 
+2

Perché 'ptr_vector' è meglio allora' vector '. Quando dici che qualcosa è meglio, qualcos'altro descrive la tua metrica. – tomas789

+1

Ci sono molti motivi per cui 'ptr_vector's è migliore, puoi [leggilo qui] (http://www.boost.org/doc/libs/1_55_0/libs/ptr_container/doc/examples.html). Ma, in poche parole, funzionano più come un vettore di riferimenti e sono, quindi, generalmente più sicuri da usare. Ad esempio, non si deviano automaticamente i puntatori e non è possibile memorizzare un puntatore 'NULL' nel vettore. – edam

+1

Ooops, volevo dire "non puoi memorizzare un puntatore' NULL' nel vettore "* di default *! – edam

2

volevo una funzionalità simile. Alla fine, ecco quello che ho fatto:

template <class T> class VectorOfRefs : public std::vector<T *> { 
public: 
    inline T & at(const uint64_t i) { 
     T * x = std::vector<T *>::at(i); 
     return *x; 
    } 
}; 

VectorOfRefs <MyType> myVector; 
myVector.push_back(&myInstance0); 
myVector.push_back(&myInstance1); 

// later in the code: 
myVector.at(i).myMethod(); 

Ovviamente questo è un vettore di puntatori sotto le coperte.

Normalmente avrei usato STL e accontentarsi di myVector.at(i)->myMethod(), ma ho voluto usare l'operatore ++, così ho avuto le seguenti due opzioni:

// using STL: 
(*myVector.at(i))++; 

// or, using my wrapper: 
myVector.at(i)++; 

trovo la notazione con l'involucro di gran lunga preferibile in termini di leggibilità del codice. Non mi piace l'involucro, di per sé, ma paga i dividendi più tardi.

Problemi correlati