QList<Something*> what is the point?



  • Hi!
    Could someone explain me what is the point to declare QList<something *>? I saw it in Qt examples several times already. But as I know QList<something> is implemented in Qt as a class which holds poiner to the array of pointers of type <something>. It means that QList<something *> is an array of pointers to pointers to <something> which doesn't make a sense.
    Maybe I don't understand something?



  • @Harb I am definitely no Qt guru at all but what you say sounds a bit wrong to me.
    QList<Foo> is a list holding Foo elements. QList<Foo*>* is a list holding pointers to Foo objects (or nullptr).

    QList uses templates. The thing between the < > brackets is the type which the list will hold. Hence <Foo> will be a list of the "real big / actual" Foo objects while <Foo*> will just be a list of pointers.



  • @Joel-Bodenmann nono, it make a sense if you use QVector<something>. Because QVector<someting> is an array of something in the heap. But QList is an array of poiners to something in the heap.


  • Lifetime Qt Champion

    Hi,

    When you see this in Qt's documentation/example, it means the the Something class is a QObject derived class which is non copyable. See QObject's documentation



  • Qt Containers documentation covers a bit about copy constructor. (Employee example).

    Anyway, take with a grain of salt as I'm still in process of learning C++, but as far as my knowledge goes blindly creating objects to heap and putting them in a container is prone to memory leaks, thus QScopedPointer comes to play (and the rule of three). Recently I had to work with a list of pointers (QLinkedList), and it didn't pan out like I wanted to; I was over-complicating things.



  • QList<Something*> Is usually not a good idea, except if the Something is QObject child, in that case, you are forced to store the pointer because QObject can't be stored by value in a QList.
    Rest of the time, I suggest you make your Something class a an "assignable data type", see the requirements for this. A list of Pointer is hard to manage and hard for other programmers to understand your code.


  • Moderators

    @Harb said:

    QList<something> is implemented in Qt as a class which holds poiner to the array of pointers of type <something>. It means that QList<something *> is an array of pointers to pointers to <something> which doesn't make a sense.

    The first sentence is only true if sizeof(Something) > sizeof(void*). Otherwise, QList stores it directly.

    So, QList<Something*> internally stores an array of pointers to Something. There are no double-ups.

    But anyway, the current opinions among Qt devs are that QVector is usually preferable to QList.



  • @SGaist
    Yes, it is explained in QList documentation as well. But for example yesterday I met that while studying Simple Tree Model example. In this example TreeItem class contain QList<TreeItem* > property, which is apparently a list of child items. TreeItem is not derived from QObject.
    @JKSH
    Yes, tnx! I found it in QList documentation. But as I said before I was perplexed, because of that QList<TreeItem* > thing. sizeof(TreeItem) > sizeof(void *) it means that QList<TreeItem> will store array of pointers to TreeItem. So, there is no point to write an asteriks in this case, because it will not give any effect at all. But anyway now it becоmes clear. Thanks!


  • Moderators

    You're welcome :)

    @Harb said:

    But as I said before I was perplexed, because of that QList<TreeItem* > thing. sizeof(TreeItem) > sizeof(void *) it means that QList<TreeItem> will store array of pointers to TreeItem. So, there is no point to write an asteriks in this case, because it will not give any effect at all.

    There is an effect.

    QList<TreeItem*> list1;
    QList<TreeItem> list2;
    
    // ...
    // Put 100000 TreeItems into list1, and another 100000 TreeItems into list2
    // ...
    
    QList<TreeItem*> list1copy = list1; // This copies 100000 pointers (so you don't get any new TreeItems)
    QList<TreeItem> list2copy = list2; // This copies 100000 TreeItems (so you get 100000 new TreeItems)
    


  • @JKSH thanks for that great example! I didn't think about that. But I want to continue your reasoning, and add something. As I know Qt implement implicit sharing. So, in fact

    QList<TreeItem*> list1copy = list1; // No any copies
    QList<TreeItem> list2copy = list2; // No any copies

    but than if we write

    list1[0]->MethodWhichChangeTreeItem(); //Still no copies.
    list2[0].MethodWhichChangeTreeItem(); // 100000 TreeItems copies

    and than
    list1[0]=NULL; //100000 pointers copies

    Am I right?



  • Your question is really about "why we use pointers"? and "why we need container of pointers?".

    People who claim that list of pointers is evil may provide you list of disadvantages, but forget that often there is no any alternative or alternatives are inefficient and depending on the circumstances may lead to even less readable code


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.