2009-04-25 19 views
5

Cosa ne pensi? È corretto o ci sono perdite di memoria?QList e shared_ptr

Fonte:

#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; 
} 

uscita:

6 
destroying A(6) 
+2

Come sidenote: non utilizzare 'QList ' 'dove sizeof (T)> sizeof (void *)' (e sizeof (shared_ptr ) == '2 * sizof (void *)', di solito), dato che in quel caso 'QList' copia-'nuova' gli elementi nella lista (invece di mantenerla per valore). Usa invece 'QVector' o' std :: vector'. –

risposta

1

Sembra corretto. Il parametro shared_ptr di Boost è un puntatore di conteggio dei riferimenti. Il conteggio dei riferimenti è in grado di recuperare memoria se non ci sono riferimenti circolari tra gli oggetti. Nel tuo caso, gli oggetti di classe A non fanno riferimento a nessun altro oggetto. Pertanto, puoi usare shared_ptr senza preoccupazioni. Inoltre, la semantica della proprietà consente l'uso di shared_ptrs nei contenitori STL (e Qt).

1

E 'difficile suggerire qualcosa senza sapere perché l'elenco dei shared_ptr s di A oggetti esistono in primo luogo.

Dai uno sguardo allo ownership semantics di puntatori intelligenti. Forse per aiutarti.

Alcune altre cose che possono essere migliorate:

1. liste Uso di inizializzazione in ctor come:

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

2.int _tmain(int argc, _TCHAR* argv[]) non è una firma standard;

Usa

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

o semplicemente:

int main() 
+0

Non sono sicuro di cosa intendi con il tuo primo punto. Dove dovrei usare gli elenchi di inizializzatori? '_tmain' era l'impostazione predefinita quando si utilizzava la procedura guidata di Visual Studio, ma grazie per questo suggerimento! – WolfgangA

+1

_tmain (int argc, _TCHAR * argv []) è una firma valida su VC++ :). È un metodo principale che accetta argomenti multibyte o unicode, a seconda di uno switch in VS. C'è anche un int wmain (int argc, wchar_t * argv []). – Skurmedel

+0

Un'implementazione può fornire N diverse firme di main. Il linguaggio Standard ne definisce solo due (ho menzionato sopra). – dirkgently

1

Questo codice è perfettamente bene.

Se stai cercando un consiglio forse potresti fornire maggiori informazioni sullo scopo dell'utilizzo di shared_ptr con QList, potrebbe esserci un modo "Qt" per farlo senza tirare fuori le grosse pistole come shared_ptr.

+1

che non è del tutto corretto. è possibile utilizzare l'albero di proprietà degli oggetti di Qt come layout, passando QList come proprietario di ciascun oggetto inserito. è una tecnica molto utile quando si lavora con Qt. leggi di più qui: http://doc.trolltech.com/4.5/objecttrees.html –

+0

@daniel Questa non è un'opzione, perché i genitori e i bambini devono essere sottoclassi QObject per farlo funzionare. QList non è un QObject quindi è un no go anche se A ereditato da QObject. –

1

Se non si utilizza un puntatore intelligente, è necessario eliminare gli elementi dell'elenco da soli.

Fonte:

#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; 
} 

uscita:

6 

Non va bene.

+0

Quindi basta rimuovere l'operatore "nuovo" e gli oggetti A verranno decostruiti quando la QList è. –

Problemi correlati