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

How to make QList const from outside



  • #include <QCoreApplication>
    #include <QObject>
    #include <QDebug>
    
    class Item {
        public:
            QString value;
    };
    
    class Box {
        public:
            Box() {
                items.append((new Item()));
            }
    
            QList<Item*> getItems() {
                return items;
            }
    
        private:
            QList<Item*> items;
    };
    
    int main(int argc, char* argv[]) {
        QCoreApplication a(argc, argv);
    
        auto variable = new Box();
        auto items = variable->getItems();
        items.at(0)->value = "value"; // <- items shouldn't be edited from outside
        qDebug() << items.at(0)->value;
    
        return a.exec();
    }
    

    Is it possible to prevent changing items outside Box class?



  • @Cocojambo
    You can return const QList<Item*> & and declare const your function;



  • @guerinoni
    If you meant code below then it doesn't work. Still able to change outside.

    const QList<Item*>& getItems() const {
                return items;
    }
    


  • @Cocojambo
    ok, then you need to create a QList with every Item as const *Item const
    But why don't you use a simple QList<Item>?



  • @guerinoni

    class Item {
        public:
            QString value;
    };
    
    class Box {
        public:
            Box() {
                auto itm = new Item();
                items.append(*itm);
                items.at(0).value = ""; // cannot change it now
            }
            const QList<Item>& getItems() const {
                return items;
            }
        private:
            QList<Item> items;
    };
    
    int main(int argc, char* argv[]) {
        QCoreApplication a(argc, argv);
    
        auto variable = new Box();
        auto items = variable->getItems();
    }
    

    I was afraid of copying items. But now I cannot change the value inside Box class.
    My goal is get this list inside Box, give items for reading outside and change them only inside Box.



  • @Cocojambo
    Yes because you miss that .at() method return a const reference, because of this you can't edit...

            items.append(Item{"hello"});
            items.at(0).value = ""; // items.at(0) is const
            items[0].value = "hello world";
    


  • @guerinoni
    Well, then we still have previous problem :)

    int main(int argc, char* argv[]) { 
        ...
        auto variable = new Box();
        auto items = variable->getItems();
        items[0].value = "value"; // I can change it outside the class
        qDebug() << items[0].value;
    }
    


  • @Cocojambo

    #include <QtDebug>
    
    class Item
    {
    public:
        QString value;
    };
    
    class Box
    {
    public:
        Box() { items.append(Item{"hello"}); }
        const QList<Item> &getItems() const { return items; }
    
        void printAll() const
        {
            qDebug() << "len ->" << items.size();
            for (auto i : items) {
                qDebug() << i.value;
            }
            qDebug() << "";
        }
    
    private:
        QList<Item> items;
    };
    
    int main(int argc, char *argv[])
    {
        Box variable;
        variable.printAll();
    
        auto items = variable.getItems();
        items.push_back(Item{}); // edit only on items and not in variable
        variable.printAll();
    
        items[0].value = "value"; // I can change it outside the class
        variable.printAll();
    
        // if you make local variable const, you can't change it
        const auto itemsConst = variable.getItems();
        itemsConst.push_back(Item{}); // error
    }
    

    Please, this is the basic of C++



  • @guerinoni
    Thank you. But ... :) in my case assigning to new variable is redundantly each time when I want to read items from the list.
    For example, I read all the records from some mysql table to that private QList<Item> items and work with these records in any part of my code in read only mode (without creation such itemsConst variable).


  • Lifetime Qt Champion

    @Cocojambo said in How to make QList const from outside:

    to new variable is redundantly each time when I want to read items from the list.

    But that's the problem of your code. Your function returns a const ref but you copy it to a local object:

    auto items = variable.getItems();
    

    In Qt this is not that problematic due to implicit sharing, for pure c++ objects like e.g std::vector you should write

    const auto &items = variable.getItems();
    

    But again - c++ basics



  • @Christian-Ehrlicher
    "In Qt this is not that problematic due to implicit sharing"
    As I understand Qt will create another copy of QList<Item> items when I change it.

    Can I prohibit copying reference and cloning the source array as result in any way from my class? For example if someone use my class and I want to allow him only read these items (and copy some of them only via loop iteration);
    Sorry if I am asking something stupid :)


  • Lifetime Qt Champion

    @Cocojambo said in How to make QList const from outside:

    Can I prohibit copying reference and cloning the source array as result in any way from my class?

    No - it's a copy so the 'user' can do what he wants.


Log in to reply