Qt equivalent to boost::ptr_vector?

455 Views Asked by At

I need a pointer container that takes ownership of the pointers - i.e. when an element is removed, or the container goes out of scope, it frees all its pointers, like in boost::ptr_vector.

QList<QScopedPointer<AbstractClass> > doesn't work (compile errors, no copy constructor?).

Right now I'm using QList<QSharedPointer<AbstractClass> >, but it feels like an overkill, with its reference counting and the expensive mutex for multithreading.

Edit: I just learned about QPtrList (thanks @ForEveR) which was that very equivalent in Qt3, but was removed from later versions. I just don't understand why they would remove it.

2

There are 2 best solutions below

0
On BEST ANSWER

You are right that QSharedPointer is a bit of overhead for said reasons.

Unfortunately, there is not such a pointer vector in Qt and it is also a bit questionable whether it is worth adding when the language evolves and we have got good primitives in place to do similar jobs.

I have just had a quick discussion with one of the Qt core developers and it seems to be that the recommended solution for today is either QSharedPointer or this from C++11:

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

Do not get attempted using QVector instead of std::vector as QVector may want to do copies.

Do not get attempted by this solution either, even in C++11:

QList<QScopedPointer<AbstractClass>>

The problem here is that QList wants to do copies. When using any non-const method, detach will be called which makes copies and that will not compiler.

Also, QScopedPointer does not have move constructors or operators and that is by design.

3
On

Just another idea based on Qt-concepts:

You can derive the objects which the pointer in the list shows to from QObject and add a small QObect-based class, which holds the ownership for the list. Each pointer, which will added to this new-QObject-based list must set the owning list-class as its parent. Now the QObject-based list-container will take care of the cleanup with the Qt-mechanism when releasing it.

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

You can find more about the object tree ownership of Qt here: http://qt-project.org/doc/qt-4.8/objecttrees.html .

Of course this is much more overhead than using a small C++-11 type like std::unique_ptr.