2011-11-20 3 views
12

Est-il légal d'avoir un vecteur de références aux objets, comme ceci?Vecteurs de références aux objets

vector<Agent&> seenAgents; 

Qui serait par exemple rempli par certains, mais pas tous les objets de la scène? J'ai un vecteur d'objets Agent, mais le vecteur décrit ci-dessus doit contenir des références à seulement celles que chaque agent peut voir actuellement, ce qui signifie que les références seront ajoutées et supprimées tout le temps.

Est-ce quelque chose que la langue va permettre? Et en plus, y a-t-il autre chose dont je dois être conscient? Si je supprime une référence du vecteur, la conserve-t-elle? Est-ce une fuite de mémoire?

Je semblent obtenir cette erreur sur la ligne déclarant le vecteur:

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

Est-ce quelque chose à voir directement avec la ligne ou est le plus susceptible d'être le quelque part ailleurs? Il est initialisé dans les constructeurs initialiseur liste comme ceci:

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

Dupliquer de http://stackoverflow.com/questions/922360/quoi-cant-i-make-a-vector-of-references –

Répondre

19

Vous ne pouvez pas avoir vector de références, en tant que référence ne copiable cessible et tous conteneurs STL sont censés stocker copiable assignable articles.

Mais vous pouvez faire en sorte que le conteneur contienne des pointeurs. Comme ceci:

vector< Agents* > seenAgents; 

Ceci est un peu dangereux. Vous devez être sûr que ces pointeurs resteront valides. Je veux dire - si quelqu'un supprime un objet, pointé par un pointeur dans ce conteneur, le pointeur devient invalide. Vous devez être sûr que cela n'arrivera pas, car vous ne pouvez pas le vérifier (vous ne pouvez pas vérifier NULL, car un pointeur ne deviendra pas NULL, si quelqu'un supprime l'objet pointé).

La meilleure solution ici (fournie par un conteneur avec des pointeurs) serait d'utiliser des pointeurs intelligents - certains avec un nombre de références, par exemple; ils vous garantiront que l'objet existera et que le pointeur est valide. Et dans le cas où l'objet, pointé par le pointeur intelligent, est détruit, vous pouvez le vérifier pour NULL.

+2

Êtes-vous sûr que les références ne sont pas copiables? J'aurais pensé qu'ils ne sont pas assignables. – UncleBens

+0

Bien, merci. Mais vous ne pouvez toujours pas "copier" une référence, car ce n'est pas un type réel, il n'existe pas vraiment, je veux dire - aucune momory n'est allouée pour cela (dans la plupart des implémentations du compilateur, presque toutes). Mais encore - oui, 'assignable 'semble plus juste et moins confus. Édité :) –

+0

Vous ne pouvez pas par défaut les construire non plus. –

8

Vous ne pouvez pas le faire. Utilisez des pointeurs.

La bibliothèque Boost fournit PTR_VECTOR qui est une meilleure solution que:

vector<T*> foo; 
+2

Pourquoi 'ptr_vector' est-il meilleur que' vector '. Quand vous dites que quelque chose va mieux, alors quelque chose d'autre décrit votre métrique. – tomas789

+1

Il y a beaucoup de raisons pour lesquelles 'ptr_vector's sont meilleurs, vous pouvez [lire à ce sujet ici] (http://www.boost.org/doc/libs/1_55_0/libs/ptr_container/doc/examples.html). Mais, en un mot, ils fonctionnent plus comme un vecteur de références et sont, par conséquent, généralement plus sûrs à utiliser. Par exemple, vous ne dérérez pas les pointeurs vous-même et vous ne pouvez pas stocker un pointeur 'NULL' dans le vecteur. – edam

+1

Oups, je voulais dire "vous ne pouvez pas stocker un pointeur" NULL "dans le vecteur" * par défaut *! – edam

2

Je voulais des fonctionnalités similaires. En fin de compte, voici ce que je faisais:

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(); 

Évidemment, cela est un vecteur de pointeurs sous les couvertures.

Normalement, j'utiliser STL et se contenter de myVector.at(i)->myMethod(), mais je voulais utiliser l'opérateur ++, donc j'eu les deux options suivantes:

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

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

je trouve la notation avec l'emballage de loin préférable en termes de lisibilité du code. Je n'aime pas l'emballage, en soi, mais ça rapporte plus tard.

Questions connexes