2010-05-21 2 views
3

Je viens de découvrir le concept d'auto_ptr et je l'aime! Comme Qt nécessite souvent un QList ou un QVector < (certains QObject ou QWidget) *>, y a-t-il une raison concrète pour laquelle auto_ptr devrait être évité? Si je ne me trompe pas, il vous permet de remplacer ceci:Qt et auto_ptr

std::vector<MyClass*> vec; 
/* add several elements to the vector and do stuff with them */ 
for(size_t i=0; i<vec.length(); ++i) 
{ 
    delete vec[i]; 
} 
vec.clear(); 

avec somthing beaucoup plus court (pas de nettoyage)

std::vector<auto_ptr<MyClass>> vec; 
/* add several elements to the vector and do stuff with them */ 
// no need for the delete loop 

... peut-Qt travailler encore sa magie de mémoire partagée avec celle de auto_ptr? La gestion de la mémoire automagique parent-enfant fonctionne-t-elle toujours de manière transparente? Merci

+13

[Vous ne voulez pas utiliser un conteneur de 'auto_ptr' objets] (http://stackoverflow.com/ questions/111478/pourquoi-est-ce-faux-utiliser-stdauto-ptr-avec-stl-conteneurs). Vous pouvez utiliser 'shared_ptr' à la place, bien que je n'ai jamais utilisé Qt et je ne peux pas dire à quel point il joue avec les différentes formes de pointeurs intelligents. –

+1

Ou vous pouvez utiliser un conteneur conçu pour contenir des pointeurs. boost: ptr_vector

+0

@Martin, ou mieux, vous pouvez utiliser QVector, qui est également conçu comme un vecteur de pointeurs, en tenant par valeur pour les types plus petits qu'un pointeur et fournit également tous les goodies des conteneurs Qt. – CMircea

Répondre

12

Qt a ses propres classes de pointeurs intelligents qui sont à bien des égards supérieurs à std::auto_ptr, en particulier en ce que certains d'entre eux peuvent être mis dans des conteneurs sans problèmes. std::auto_ptr a une sémantique de copie de propriété-transfert, et ne fonctionnera donc pas comme prévu si vous essayez de le mettre dans un conteneur.

Essayez d'utiliser QSharedPointer. C'est un pointeur intelligent compté par référence qui supprime son objet contenu lorsqu'il n'y a plus de copies du pointeur intelligent à gauche. Contrairement à std::auto_ptr il peut y avoir plusieurs copies de la même QSharedPointer, et donc il joue bien avec les conteneurs.

+0

Un QSharedPointer est-il mieux comparable au boost :: shared_ptr ou au standard std :: tr1: shared_ptr? –

+1

Ils ont la même sémantique, et je ne peux penser à rien de l'un d'eux qui serait un avantage sur l'autre. Mais si le projet utilise déjà Qt, il ne serait pas logique d'introduire une dépendance sur boost ou sur les extensions TR1 juste pour utiliser ces classes. –

1

std::auto_ptr ne peut pas être utilisé dans std::vector, parce std::vector pense pouvoir copier son contenu, et vous ne pouvez pas copier un std::auto_ptr dans le sens normal. Copier signifie se retrouver avec deux choses identiques, et si vous aviez deux std::auto_ptr s identiques, ce qu'ils pointaient serait doublé quand ils sortiraient de la portée. (Ce qui se passe est plutôt que le auto_ptr être copié à partir a son pointeur interne remis à zéro, et celui d'être copié est maintenant ce que l'ancien était.)

Utilisez shared_ptr, qui est souvent disponible boost::shared_ptr ou sur Visual C++ std::tr1::shared_ptr, et qui sera dans la bibliothèque standard C++ 0x, ou utiliser tout ce que Qt a. Ceux-ci peuvent être copiés, et peuvent donc aller dans des conteneurs.

2

Si vous voulez un conteneur qui a la propriété de pointeurs, regardez les conteneurs de pointeurs de boost. Vous placez des pointeurs dans le conteneur, mais comme les autres conteneurs, ils sont traités comme des objets normaux, ce qui facilite leur utilisation avec des algorithmes standard (pas besoin d'écrire des classes wrapper). Lorsque le conteneur de pointeur est hors de portée, il appellera supprimer tous les pointeurs dans le conteneur:

boost::ptr_vector<MyClass> v; 
v.push_back(new MyClass(12)); 

std::for_each(v.begin(), v.end(), DoStuff()); 

// Destroyed here.