Qt equivalent to boost::ptr_vector?
Asked Answered
M

2

6

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.

Mercurio answered 17/12, 2014 at 10:16 Comment(4)
Wow, interesting question, but yeah, QScopedPointer is not meant to be copied as that holds single ownership.Lusty
Are you happy with a C++11 solution or do you need to support the standard before that, too? unique_ptr can be put into a std::vector, at least. QVector is trickier.Lusty
@lpapp I'm on VS2010 for that project, so I can't personally use C++11.Mercurio
oh, that is unfortunate, QSharedPointer it is, then.Lusty
D
4

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.

Dishman answered 17/12, 2014 at 10:43 Comment(0)
W
0

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.

Wagshul answered 17/12, 2014 at 10:53 Comment(3)
Interesting trick, but you drop most of the list functionality this way, so e.g. you will not be able to use this where you could use normal containers. You probably need a getter to the "real" list, but then you have the issue of reparenting; hmm, it is not trivial :)Lusty
YOu're right, that is the reasone I just marked this as an idea to use the Qt-base stuff. I guess much to much overhead for a small list with pointers.Wagshul
I appreciate your idea. It is an interesting trick, indeed, and one more option to consider. The overhead might or might not be still lower than with QSharedPointers if the cons are acceptable for this idea. Not sure about the overhead differences as the parent/child tree also keeps track of things, counting and all that, so it may be slightly slower as well as faster in the end. Benchmarks would show.Lusty

© 2022 - 2024 — McMap. All rights reserved.