Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QList: Convenient way to deep copy a pointer list?
QtWS25 Last Chance

QList: Convenient way to deep copy a pointer list?

Scheduled Pinned Locked Moved General and Desktop
6 Posts 3 Posters 5.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Asperamanca
    wrote on last edited by
    #1

    Let's say I have a list of pointers, like so:
    QList<MyObject*> list;

    MyObject has a valid copy constructor and assignment operator.
    Is there a simple way to create a new list that is a deep copy of 'list'?

    Something like this:
    QList<MyObject*> copyOfList = qDeepCopy(list);

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi
      What does using operator = yield?
      http://doc.qt.io/qt-5/qlist.html#operator-eq

      A 1 Reply Last reply
      1
      • mrjjM mrjj

        Hi
        What does using operator = yield?
        http://doc.qt.io/qt-5/qlist.html#operator-eq

        A Offline
        A Offline
        Asperamanca
        wrote on last edited by
        #3

        @mrjj said in QList: Convenient way to deep copy a pointer list?:

        Hi
        What does using operator = yield?
        http://doc.qt.io/qt-5/qlist.html#operator-eq

        Depending on whether the type is marked as moveable or not, it either calls the copy constructor of T (the copy constructor of a pointer thus copying the pointer - not the content), or std::move or memcpy...the code gets a little complex there.

        1 Reply Last reply
        1
        • mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Oh so in the other copy of the list,
          it should not point to same T* but create new instances (of T) and change the new list to point to these?
          Sorry, that im pretty sure you must implement yourself. :)

          You could derive from QList and make overloaded = that does it for you but
          might be overkill.

          If MyObject is QObject based, you might get issues cloning them but I assume newing it / copy ctor is
          already working ?

          raven-worxR 1 Reply Last reply
          0
          • mrjjM mrjj

            Oh so in the other copy of the list,
            it should not point to same T* but create new instances (of T) and change the new list to point to these?
            Sorry, that im pretty sure you must implement yourself. :)

            You could derive from QList and make overloaded = that does it for you but
            might be overkill.

            If MyObject is QObject based, you might get issues cloning them but I assume newing it / copy ctor is
            already working ?

            raven-worxR Offline
            raven-worxR Offline
            raven-worx
            Moderators
            wrote on last edited by raven-worx
            #5

            @mrjj said in QList: Convenient way to deep copy a pointer list?:

            You could derive from QList and make overloaded = that does it for you but
            might be overkill.

            no need to. QList internally uses template methods. So implementing those methods directly for the custom type is already enough.

            Unfortunately i can't tell you what the correct settings are, since i don't have time to check it in the sources right now.
            But the first thing to change the behavior of QList is to generate QTypeInfo and the QList::node_construct():

            template <>
            class QTypeInfo<MyType>
            {
            public:
                enum {
                    isPointer = true,
                    isComplex = true,
                    isStatic = false,
                    isLarge = false,
                    isDummy = false
                };
                static inline const char *name() { return "MyType"; }
            };
            
            template <>
            Q_INLINE_TEMPLATE void QList<MyType>::node_construct(Node *n, const MyType &t)
            {
                if (QTypeInfo<EyeOmsVariant>::isComplex)
                        new (n) MyType(t);
                else
                     ::memcpy(n, &t, sizeof(MyType));
            }
            

            Add something like this (implement it correctly) and the compiler will use them, instead creating them on-the-fly when needed.
            (read on C++ templates for details).

            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
            If you have a question please use the forum so others can benefit from the solution in the future

            1 Reply Last reply
            2
            • A Offline
              A Offline
              Asperamanca
              wrote on last edited by
              #6

              Thanks, but this is indeed overkill for my use case. I was hoping for an existing template method in the veins of qDeleteAll. If I come across this more often, I'll write it myself.

              BTW I wouldn't do type-specific template overloading in this case. Who says that I always want to deep-copy a pointer list of a certain type? But it's an interesting approach, I didn't think of that. Thanks again!

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved