2014-12-17 9 views
6

Ho bisogno di un contenitore di puntatori che assuma la proprietà dei puntatori, ovvero quando un elemento viene rimosso o il contenitore non rientra nell'ambito, libera tutti i suoi puntatori, come in boost::ptr_vector.Qt equivalente a boost :: ptr_vector?

QList<QScopedPointer<AbstractClass> > non funziona (errori di compilazione, nessun costruttore di copia?).

In questo momento sto usando QList<QSharedPointer<AbstractClass> >, ma sembra un eccessivo, con il suo conteggio dei riferimenti e il costoso mutex per il multithreading.

Edit: Ho appena imparato a conoscere QPtrList (grazie @ForEveR) che era quella equivalente in Qt3, ma è stato rimosso da versioni successive. Non capisco perché lo rimuovono.

+0

Wow, domanda interessante, ma sì, QScopedPointer non è pensato per essere copiato in quanto detiene la proprietà singola. – lpapp

+0

Sei soddisfatto di una soluzione C++ 11 o hai bisogno di supportare lo standard anche prima? unique_ptr può essere messo in un vettore std ::, almeno. QVector è più complicato. – lpapp

+0

@lpapp Sono su VS2010 per quel progetto, quindi non posso usare personalmente C++ 11. – sashoalm

risposta

4

Hai ragione che QSharedPointer è un po 'sovraccarico per tali ragioni.

Sfortunatamente, non c'è un tale vettore di puntatore in Qt ed è anche un po 'discutibile se valga la pena aggiungere quando il linguaggio si evolve e abbiamo delle buone primitive per fare lavori simili.

Ho appena avuto una rapida discussione con uno degli sviluppatori principali Qt e sembra essere il fatto che la soluzione consigliata per oggi è o QSharedPointer o questo da C++ 11:

std::vector<std::unique_ptr<AbstractClass>> 

Do not Get ha tentato di utilizzare QVector invece di std :: vector poiché QVector potrebbe voler fare delle copie.

non ottengono tentato da questa soluzione sia, anche in C++ 11:

QList<QScopedPointer<AbstractClass>> 

Il problema qui è che QList vuole fare copie. Quando si usa un metodo non const, viene chiamato il detach che fa le copie e non il compilatore.

Inoltre, QScopedPointer non ha costruttori o operatori di spostamento e that is by design.

0

Solo un altro idea sulla base di Qt-concetti:

è possibile derivare gli oggetti che il puntatore nella lista mostra a da QObject e aggiungere una piccola classe QObect-based, che detiene la proprietà per l'elenco. Ogni puntatore, che verrà aggiunto a questo nuovo elenco basato su QObject, deve impostare come proprietario la classe di elenco proprietaria. Adesso il list-container basato su QObject si prenderà cura della pulizia con il meccanismo Qt quando lo rilascerà.

class Ptr : public QObject { 
}; 

class MyList : public QObject { 
    QList<Ptr> m_myList; 

public: 
    void add(Ptr *item) { 
     m_mylist.push_back(item); 
     item->setParent(this); 
    } 
}; 

Potete trovare ulteriori circa la proprietà dell'oggetto albero di Qt qui: http://qt-project.org/doc/qt-4.8/objecttrees.html.

Ovviamente questo è molto più sovraccarico rispetto all'utilizzo di un piccolo tipo C++-11 come std :: unique_ptr.

+0

Interessante trucco, ma in questo modo si elimina la maggior parte delle funzionalità dell'elenco, quindi ad es.non sarai in grado di usarlo dove potresti usare contenitori normali. Probabilmente hai bisogno di un getter per la "vera" lista, ma poi hai il problema di reparenting; hmm, non è banale :) – lpapp

+0

Hai ragione, questo è il commento che ho appena indicato come idea per usare la roba di Qt-base. Immagino molto di troppo per una piccola lista con i puntatori. – KimKulling

+0

Risolto il problema della grammatica. – KimKulling