2010-09-29 6 views
16

J'ai besoin d'un conteneur de pointeurs. Recommanderiez-vous boost::ptr_vector<T> ou std::vector<boost::shared_ptr<T> >? (Ou quelque chose d'autre?)Dois-je utiliser boost :: ptr_vector <T> ou vectoriel <boost :: shared_ptr <T>>?

Si cela est intéressant, ma structure de données réelle est relativement compliquée (voir here) et stocke actuellement des objets, pas des pointeurs, mais je voudrais changer cela (en utilisant des conteneurs pointeur), afin pour se débarrasser de la copie inutile:

typedef std::multimap<Foo0, std::map<int, double> > VecElem; 
std::vector<VecElem> vec; 
+0

où cette copie inutile se produit-elle? –

+0

@Idan: Chaque fois que vous insérez quelque chose dans le vecteur ou le multimap d'en haut. – Frank

+3

@Idan: Lorsque vous avez un conteneur qui stocke des pointeurs, seul le pointeur sera copié lors de l'ajout de données, lorsque vous stockez des objets, les objets réels seront copiés. C'est un problème quand vous traitez avec des objets qui sont chers à copier. – sbi

Répondre

30

Qui est propriétaire de l'objet? Si le conteneur est propriétaire des objets (ce qui signifie que les objets ne doivent pas dépasser le conteneur), utilisez un ptr_vector. Sinon, utilisez un vecteur de shared_ptr s. Les conteneurs de bibliothèque standard (tels que std::vector ou std::list) possèdent les objets qu'ils contiennent, donc la sémantique d'un ptr_vector est plus proche de cela.

+0

Add'l question: est-ce qu'un 'vecteur' de' unique_ptr' est identique à 'ptr_vector'? –

+0

@Didier: Je n'en connais pas assez sur 'unique_ptr' pour répondre à cette question. Cependant, le 'ptr_vector' aura moins de frais généraux (comme @sbi le souligne dans sa réponse). –

+8

@Didier: non, 'ptr_vector' autorise la copie du' vecteur', qui copie en profondeur le contenu (en utilisant la fonction libre 'new_clone') et permet ainsi les conteneurs polymorphes. Il a également une interface plus agréable (déréférencer l'itérateur donne une référence à l'objet, pas une référence au pointeur vers l'objet) et d'autres goodies. –

13

shared_ptr<> possède une sémantique propriétaire partagée, qui est implémentée par incrémentation et décrémentation des comptages de référence. Cela vient avec une surcharge, surtout quand le multi-thread est activé (parce que ces compteurs doivent être verrouillés).

Si vos objets sont partagés, utilisez shared_ptr<>. Mais si elles sont effectivement détenues par le conteneur et qu'elles doivent mourir avec le conteneur, les références (pointeurs) distribuées peuvent également disparaître lorsque le conteneur meurt, puis utiliser des conteneurs de pointeurs, car leur charge est moindre.
Si vous n'êtes pas sûr, utilisez le shared_ptr pour des raisons de sécurité. S'il s'avère que vous avez un problème de performance, vous pouvez toujours l'optimiser plus tard. (Il est plus facile d'optimiser un système de travail que de faire fonctionner un système prématurément optimisé.)

+6

+1 pour 'Il est plus facile d'optimiser un système de travail que de faire fonctionner un système prématurément optimisé. ' – balki

+0

+1 pour _" devrait mourir avec le conteneur "_. – mskfisher

Questions connexes