Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QList and smart pointers



  • I am trying to avoid using raw pointers and prioritizing the use of smart pointers, but I have a class that has an attribute of type QList. This attribute must be a list of objects of a custom type, for example called MyCustomObj. I read somewhere that Qt containers only store objects that have a copy builder, and this is not the case with unique_prt. That way it wouldn't work QList<std::unique_ptr<MyCustomObj>> my_prop;.

    Is there another alternative or in this case I can not escape the raw pointers?

    QList<MyCustomObj*> my_prop;



  • @Exotic_Devel This is a general limitation of all Qt containers - all of them can store only assignable data types. See https://doc.qt.io/qt-5/containers.html. You need either to change container (e.g. to std::vector) or change smart pointer to assignable (e.g., std::shared_ptr)


  • Moderators

    There's a fundamental rule when using Qt:

    Do not use std smart pointers with it.

    Any object, that has at it's core the QObject class, will not work correctly or even crash when used with smart pointers.

    If you really want to use them, e.g: you don't trust your or your colleagues memory management skills, than use QPointer instead
    https://doc.qt.io/qt-5/qpointer.html


  • Moderators

    @J-Hilk said in QList and smart pointers:

    use QPointer instead
    https://doc.qt.io/qt-5/qpointer.html

    QPointer does not manage memory in any way. It's only use is to be able to tell (reliably) whether a pointer is nullptr or not.

    @Exotic_Devel if your object derives from QObject, @J-Hilk is right - don't use smart pointers, rather leverage parent-child structure of QObjects - Qt will clean them up for you. If you have QObjects that are not part of any structure, you can use QSharedPointer or QScopedPointer (even in a list). If your object is not a QObject at all - feel free to use any smart pointers you like.



  • @Exotic_Devel said in QList and smart pointers:

    Is there another alternative or in this case I can not escape the raw pointers?

    You can use smart pointers to hold you item in your QList, for example QSharedPointer<MyCustomObj>.
    If you type is base on QObject, you have to take care to avoid double free if they have a parent.
    Therefore you have to create you smart pointer instance like this:

    auto obj=QSharedPointer<MyCustomObj>(new MyCustomObj, &QObject::deleteLater);
    

    hope this help



  • @J-Hilk said in QList and smart pointers:

    There's a fundamental rule when using Qt:

    Do not use std smart pointers with it.

    There is no such rule.

    Any object, that has at it's core the QObject class, will not work correctly or even crash when used with smart pointers.

    This is total BS.



  • @Exotic_Devel This is a general limitation of all Qt containers - all of them can store only assignable data types. See https://doc.qt.io/qt-5/containers.html. You need either to change container (e.g. to std::vector) or change smart pointer to assignable (e.g., std::shared_ptr)



  • @KroMignon said in QList and smart pointers:

    auto obj=QSharedPointer<MyCustomObj>(new MyCustomObj, &QObject::deleteLater);

    Your post interested me. I read some articles on this and I get the idea that you should not mix ownership methods. QObject based system uses parent/child to express ownership. So if you use smart pointers you should not use the parent/child ownership. I explored your custom deleter strategy with std smart pointers:

        {
            // smart pointers combined with custom deleter for use with QObject based objects
            using namespace std;
    
            shared_ptr<QObject> ptr(new QObject, [](QObject* p){
                p->deleteLater();
            });
    
            unique_ptr<QObject,function<void(QObject*)>> ptr2(new QObject, [](QObject* p){
                p->deleteLater();
            });
        }
    

    I am filing this away for future use. Thanks for sharing.


Log in to reply