2009-04-25 12 views
5

Qu'en pensez-vous? Est-ce correct ou y a-t-il des fuites de mémoire?QList and shared_ptr

Source:

#include <QList.h> 
#include <boost/shared_ptr.hpp> 
#include <iostream> 

class A { 
private: 
    int m_data; 
public: 
    A(int value=0) { m_data = value; } 
    ~A() { std::cout << "destroying A(" << m_data << ")" << std::endl; } 
    operator int() const { return m_data; } 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    QList<boost::shared_ptr<A> > list; 
    list.append(boost::shared_ptr<A>(new A(6))); 
    std::cout << int(*(list.at(0))) << std::endl; 
    return 0; 
} 

Sortie:

6 
destroying A(6) 
+2

En tant que sidenote: ne pas utiliser '' QList où 'sizeof (T)> sizeof (void *)' (et 'sizeof (shared_ptr ) == 2 * sizof (void *)', en général), puisque dans ce cas, 'QList' copiera-'new' les éléments dans la liste (au lieu de le garder par valeur). Utilisez 'QVector' ou' std :: vector' à la place. –

Répondre

1

Cela semble correct. Le shared_ptr de Boost est un pointeur de comptage de référence. Le comptage des références est capable de récupérer de la mémoire s'il n'y a pas de références circulaires entre les objets. Dans votre cas, les objets de classe A ne référencent aucun autre objet. Ainsi, vous pouvez utiliser shared_ptr sans soucis. De même, les sémantiques de propriété permettent d'utiliser shared_ptrs dans les conteneurs STL (et Qt).

1

Il est difficile de proposer quoi que ce soit, sans savoir pourquoi la liste des shared_ptr s de A objets existent en premier lieu.

Jetez un oeil à la ownership semantics des pointeurs intelligents. Peut-être d'aide à vous.

D'autres choses qui peuvent être améliorés:

1. utiliser des listes de initialiseur dans cteur comme:

class A { 
private: 
    int m_data; 
public: 
    A(int value=0) : m_data (value) {} 
// .... 

2.int _tmain(int argc, _TCHAR* argv[]) n'est pas une signature standard;

Utilisez

int main(int argc, char* argv[]) 

ou tout simplement:

int main() 
+0

Je ne suis pas sûr de ce que vous voulez dire par votre premier point. Où dois-je utiliser les listes d'initialisation? '_tmain' était la valeur par défaut lors de l'utilisation de l'assistant Visual Studio, mais merci pour cet indice! – WolfgangA

+1

_tmain (int argc, _TCHAR * argv []) est une signature valide sur VC++ :). C'est une méthode principale qui prend des arguments multi-octets ou unicode, en fonction d'un changement dans VS. Il y a aussi un int wmain (int argc, wchar_t * argv []). – Skurmedel

+0

Une implémentation peut fournir N signatures différentes de main. Le langage Standard ne définit que deux (j'ai mentionné ci-dessus). – dirkgently

1

Ce code semble parfaitement bien. Si vous demandez des conseils, vous pourriez fournir plus d'informations sur l'utilisation de shared_ptr avec QList, il pourrait y avoir un moyen "Qt" de le faire sans tirer sur les gros canons comme shared_ptr.

+1

ce n'est pas tout à fait correct. vous pouvez utiliser l'arbre de propriété de l'objet de Qt comme disposition, en passant le QList en tant que propriétaire de chaque objet inséré. C'est une technique très utile lorsque vous travaillez avec Qt. En savoir plus à ce sujet ici: http://doc.trolltech.com/4.5/objecttrees.html –

+0

@daniel Ce n'est pas une option ici, car les parents et les enfants doivent être des sous-classes QObject pour que cela fonctionne. QList n'est pas un QObject, donc c'est un non, même si A a hérité de QObject. –

1

Si vous n'utilisez pas de pointeur intelligent, vous devez supprimer les éléments de la liste par vous-même.

Source:

#include <QList.h> 
#include <boost/shared_ptr.hpp> 
#include <iostream> 

class A { 
private: 
    int m_data; 
public: 
    A(int value=0) { m_data = value; } 
    ~A() { std::cout << "destroying A(" << m_data << ")" << std::endl; } 
    operator int() const { return m_data; } 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    QList<A *> list; 
    list.append(new A(6)); 
    std::cout << int(*(list.at(0))) << std::endl; 
    return 0; 
} 

Sortie:

6 

Pas bon.

+0

Ensuite, il suffit de retirer le "nouveau" opérateur et les objets A seront déconstruits lorsque le QList est. –