Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. trying to understand smart pointers...
Forum Updated to NodeBB v4.3 + New Features

trying to understand smart pointers...

Scheduled Pinned Locked Moved Solved C++ Gurus
30 Posts 6 Posters 5.1k Views 3 Watching
  • 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.
  • M Offline
    M Offline
    mzimmers
    wrote on 19 Nov 2023, 04:42 last edited by mzimmers
    #1

    ...but I don't understand what's wrong with this code:

    QString qs = "xxx";
    QString *qsp;
    std::unique_ptr<QString> qsp2;
    
    qsp = &qs;
    list.append(qsp); // works
    list2.append(qsp2); // doesn't compile
    

    The error message is:

    C:\Users\michael.zimmers\Qt_projects\qscopedpointer\main.cpp:16: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = QString; _Dp = std::default_delete<QString>]'
    

    This occurs with QScopedPointer as well. Is it not possible to put unique_ptr objects into a QList?

    EDIT: I omitted a couple of rather important lines in my text sample above; this is what it should be (apologies):

    QString qs = "xxx";
    
    QList<QString *> list;
    QList<std::unique_ptr<QString>> list2;
    
    QString *qsp;
    std::unique_ptr<QString> qsp2;
    
    qsp = &qs;
    // how to assign to qsp2?
    
    list.append(qsp);
    list2.append(qsp2);
    

    Thanks...

    C M 2 Replies Last reply 19 Nov 2023, 06:49
    0
    • M mzimmers
      19 Nov 2023, 04:42

      ...but I don't understand what's wrong with this code:

      QString qs = "xxx";
      QString *qsp;
      std::unique_ptr<QString> qsp2;
      
      qsp = &qs;
      list.append(qsp); // works
      list2.append(qsp2); // doesn't compile
      

      The error message is:

      C:\Users\michael.zimmers\Qt_projects\qscopedpointer\main.cpp:16: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = QString; _Dp = std::default_delete<QString>]'
      

      This occurs with QScopedPointer as well. Is it not possible to put unique_ptr objects into a QList?

      EDIT: I omitted a couple of rather important lines in my text sample above; this is what it should be (apologies):

      QString qs = "xxx";
      
      QList<QString *> list;
      QList<std::unique_ptr<QString>> list2;
      
      QString *qsp;
      std::unique_ptr<QString> qsp2;
      
      qsp = &qs;
      // how to assign to qsp2?
      
      list.append(qsp);
      list2.append(qsp2);
      

      Thanks...

      C Offline
      C Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 19 Nov 2023, 06:49 last edited by Christian Ehrlicher
      #2

      @mzimmers said in trying to understand smart pointers...:

      Is it not possible to put unique_ptr objects into a QList?

      Not when the QList contains a pointer of QStrings since a pointer to a QString and std::unique_ptr<QString> are two different types.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      0
      • M mzimmers
        19 Nov 2023, 04:42

        ...but I don't understand what's wrong with this code:

        QString qs = "xxx";
        QString *qsp;
        std::unique_ptr<QString> qsp2;
        
        qsp = &qs;
        list.append(qsp); // works
        list2.append(qsp2); // doesn't compile
        

        The error message is:

        C:\Users\michael.zimmers\Qt_projects\qscopedpointer\main.cpp:16: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = QString; _Dp = std::default_delete<QString>]'
        

        This occurs with QScopedPointer as well. Is it not possible to put unique_ptr objects into a QList?

        EDIT: I omitted a couple of rather important lines in my text sample above; this is what it should be (apologies):

        QString qs = "xxx";
        
        QList<QString *> list;
        QList<std::unique_ptr<QString>> list2;
        
        QString *qsp;
        std::unique_ptr<QString> qsp2;
        
        qsp = &qs;
        // how to assign to qsp2?
        
        list.append(qsp);
        list2.append(qsp2);
        

        Thanks...

        M Offline
        M Offline
        Mesrine
        wrote on 19 Nov 2023, 08:05 last edited by
        #3

        @mzimmers

        I think appending to a list tries to make a copy of the smart pointer, but this by definition of the unique_ptr class deletes the object. Try doing

        list2.append(std::move(qsp2));
        

        or

        list2.append(make_unique<QString>("qsp2 string"));
        
        M 1 Reply Last reply 19 Nov 2023, 14:49
        0
        • M Mesrine
          19 Nov 2023, 08:05

          @mzimmers

          I think appending to a list tries to make a copy of the smart pointer, but this by definition of the unique_ptr class deletes the object. Try doing

          list2.append(std::move(qsp2));
          

          or

          list2.append(make_unique<QString>("qsp2 string"));
          
          M Offline
          M Offline
          mzimmers
          wrote on 19 Nov 2023, 14:49 last edited by
          #4

          @Mesrine thanks for the suggestions, but that doesn't compile either (essentially the same error). I think you're right about the unique_ptr not permitting copies. That makes me wonder if I'm misusing the unique_ptr, or if there's a better construct for me to use.

          C S 2 Replies Last reply 19 Nov 2023, 16:08
          0
          • M mzimmers
            19 Nov 2023, 14:49

            @Mesrine thanks for the suggestions, but that doesn't compile either (essentially the same error). I think you're right about the unique_ptr not permitting copies. That makes me wonder if I'm misusing the unique_ptr, or if there's a better construct for me to use.

            C Offline
            C Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on 19 Nov 2023, 16:08 last edited by Christian Ehrlicher
            #5

            @mzimmers said in trying to understand smart pointers...:

            thanks for the suggestions, but that doesn't compile either (essentially the same error). I think you're right about the unique_ptr not permitting copies. That makes me wonder if I'm misusing the unique_ptr, or if there's a better construct for me to use.

            This is complete bs.
            A QString* and QSharedPointer<QString> are two comletelty different types so are QList<QString*> and QList<QSharedPointer<QString>> - they can not be implicitly converted to each other.

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            M 1 Reply Last reply 19 Nov 2023, 16:17
            0
            • M mzimmers
              19 Nov 2023, 14:49

              @Mesrine thanks for the suggestions, but that doesn't compile either (essentially the same error). I think you're right about the unique_ptr not permitting copies. That makes me wonder if I'm misusing the unique_ptr, or if there's a better construct for me to use.

              S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 19 Nov 2023, 16:09 last edited by
              #6

              @mzimmers hi,

              The first question is: why a pointer to a QString ? AFAIK, 99.99% of the time you do not need a pointer to a QString.

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • C Christian Ehrlicher
                19 Nov 2023, 16:08

                @mzimmers said in trying to understand smart pointers...:

                thanks for the suggestions, but that doesn't compile either (essentially the same error). I think you're right about the unique_ptr not permitting copies. That makes me wonder if I'm misusing the unique_ptr, or if there's a better construct for me to use.

                This is complete bs.
                A QString* and QSharedPointer<QString> are two comletelty different types so are QList<QString*> and QList<QSharedPointer<QString>> - they can not be implicitly converted to each other.

                M Offline
                M Offline
                mzimmers
                wrote on 19 Nov 2023, 16:17 last edited by
                #7

                @Christian-Ehrlicher said in trying to understand smart pointers...:

                A QString* and QSharedPointer<QString> are two comletelty different types so are QList<QString*> and QList<QSharedPointer<QString>> - they can not be implicitly converted to each other.

                In my example, I have two lists:

                QList<QString *> list;
                QList<std::unique_ptr<QString>> list2;
                

                and I'm trying to append to each:

                list.append(qsp);
                list2.append(qsp2);
                

                So I don't understand your comment.

                @SGaist I just used a QString to simplify my example. In my app, I need a list of an class that I'm subclassing. If I just maintain a list of the parent class, I can't add subclasses to the list (at least, I don't see how I can). I'm attempting to use a list of pointers to avoid this problem; if there's a better way, I'd love to hear about it.

                C 1 Reply Last reply 19 Nov 2023, 16:31
                0
                • M mzimmers
                  19 Nov 2023, 16:17

                  @Christian-Ehrlicher said in trying to understand smart pointers...:

                  A QString* and QSharedPointer<QString> are two comletelty different types so are QList<QString*> and QList<QSharedPointer<QString>> - they can not be implicitly converted to each other.

                  In my example, I have two lists:

                  QList<QString *> list;
                  QList<std::unique_ptr<QString>> list2;
                  

                  and I'm trying to append to each:

                  list.append(qsp);
                  list2.append(qsp2);
                  

                  So I don't understand your comment.

                  @SGaist I just used a QString to simplify my example. In my app, I need a list of an class that I'm subclassing. If I just maintain a list of the parent class, I can't add subclasses to the list (at least, I don't see how I can). I'm attempting to use a list of pointers to avoid this problem; if there's a better way, I'd love to hear about it.

                  C Offline
                  C Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on 19 Nov 2023, 16:31 last edited by Christian Ehrlicher
                  #8

                  @mzimmers said in trying to understand smart pointers...:

                  So I don't understand your comment.

                  You're right - I did not see there is list and list2

                  QList needs an copyable type. Use std::vector - it works also with move-only types.

                  std::vector<std::unique_ptr<QString>> l;
                  l.push_back(std::make_unique<QString>(""));
                  

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  M 1 Reply Last reply 19 Nov 2023, 17:07
                  1
                  • C Christian Ehrlicher
                    19 Nov 2023, 16:31

                    @mzimmers said in trying to understand smart pointers...:

                    So I don't understand your comment.

                    You're right - I did not see there is list and list2

                    QList needs an copyable type. Use std::vector - it works also with move-only types.

                    std::vector<std::unique_ptr<QString>> l;
                    l.push_back(std::make_unique<QString>(""));
                    
                    M Offline
                    M Offline
                    mzimmers
                    wrote on 19 Nov 2023, 17:07 last edited by
                    #9

                    @Christian-Ehrlicher I'd like to pursue using QList, if only for my education. I've added a struct to the exercise:

                    struct TestStruct {
                    	int i;
                    	TestStruct() {}
                    	TestStruct(TestStruct &ts) {i = ts.i;}
                    };
                    TestStruct myStruct;
                    
                    std::unique_ptr<TestStruct> *uniquePtr;
                    QList<std::unique_ptr<TestStruct>> list2;
                    uniquePtr = &myStruct; // how to form this?
                    list2.append(uniquePtr); // how to form this?
                    

                    It seems to be wrong to try to assign to a unique_ptr; I see an assignment operator in the docs, but there's also a proviso:
                    Copy assignment (4) to a unique_ptr type is not allowed (deleted signature).
                    So, again, this leaves me thinking I really don't understand how to use unique_ptrs. Can they be modified after they're constructed?

                    C 1 Reply Last reply 19 Nov 2023, 17:44
                    0
                    • M mzimmers
                      19 Nov 2023, 17:07

                      @Christian-Ehrlicher I'd like to pursue using QList, if only for my education. I've added a struct to the exercise:

                      struct TestStruct {
                      	int i;
                      	TestStruct() {}
                      	TestStruct(TestStruct &ts) {i = ts.i;}
                      };
                      TestStruct myStruct;
                      
                      std::unique_ptr<TestStruct> *uniquePtr;
                      QList<std::unique_ptr<TestStruct>> list2;
                      uniquePtr = &myStruct; // how to form this?
                      list2.append(uniquePtr); // how to form this?
                      

                      It seems to be wrong to try to assign to a unique_ptr; I see an assignment operator in the docs, but there's also a proviso:
                      Copy assignment (4) to a unique_ptr type is not allowed (deleted signature).
                      So, again, this leaves me thinking I really don't understand how to use unique_ptrs. Can they be modified after they're constructed?

                      C Offline
                      C Offline
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on 19 Nov 2023, 17:44 last edited by Christian Ehrlicher
                      #10

                      @mzimmers said in trying to understand smart pointers...:

                      Can they be modified after they're constructed?

                      Yes, it's a normal pointer but you can't copy them - only moving is allowed. Your TestStruct is missing the move ctor and move operator.

                      list2.append(uniquePtr); // how to form this?

                      As I said - it's not possible with QList as a unique_ptr<T> is not copyable, only movable.

                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                      Visit the Qt Academy at https://academy.qt.io/catalog

                      M 1 Reply Last reply 19 Nov 2023, 18:08
                      1
                      • C Christian Ehrlicher
                        19 Nov 2023, 17:44

                        @mzimmers said in trying to understand smart pointers...:

                        Can they be modified after they're constructed?

                        Yes, it's a normal pointer but you can't copy them - only moving is allowed. Your TestStruct is missing the move ctor and move operator.

                        list2.append(uniquePtr); // how to form this?

                        As I said - it's not possible with QList as a unique_ptr<T> is not copyable, only movable.

                        M Offline
                        M Offline
                        mzimmers
                        wrote on 19 Nov 2023, 18:08 last edited by
                        #11

                        @Christian-Ehrlicher

                        sigh I new I should have taken that extra C++ class in night school...

                        OK, so I think I've added the move c'tor and move operator (though the docs are a little confusing; there's reference to a move assignment operator, which I'm not sure is the same thing). Code looks like this:

                        struct TestStruct {
                        	int i;
                        	TestStruct() {}
                        	TestStruct(TestStruct &ts) {i = ts.i;} // copy c'tor
                        	TestStruct(TestStruct &&ts) { i = ts.i; } // move c'tor
                        	TestStruct& operator=(TestStruct&& ts) { return *this; } // move operator
                        };
                        TestStruct myStruct;
                        
                        std::unique_ptr<TestStruct> *uniquePtr = nullptr;
                        QList<std::unique_ptr<TestStruct>> list;
                        uniquePtr = &myStruct; // how to form this?
                        list.push_back(*uniquePtr); // how to form this?
                        

                        What am I continuing to do wrong here?

                        Thanks...

                        C J 2 Replies Last reply 19 Nov 2023, 18:13
                        0
                        • M mzimmers
                          19 Nov 2023, 18:08

                          @Christian-Ehrlicher

                          sigh I new I should have taken that extra C++ class in night school...

                          OK, so I think I've added the move c'tor and move operator (though the docs are a little confusing; there's reference to a move assignment operator, which I'm not sure is the same thing). Code looks like this:

                          struct TestStruct {
                          	int i;
                          	TestStruct() {}
                          	TestStruct(TestStruct &ts) {i = ts.i;} // copy c'tor
                          	TestStruct(TestStruct &&ts) { i = ts.i; } // move c'tor
                          	TestStruct& operator=(TestStruct&& ts) { return *this; } // move operator
                          };
                          TestStruct myStruct;
                          
                          std::unique_ptr<TestStruct> *uniquePtr = nullptr;
                          QList<std::unique_ptr<TestStruct>> list;
                          uniquePtr = &myStruct; // how to form this?
                          list.push_back(*uniquePtr); // how to form this?
                          

                          What am I continuing to do wrong here?

                          Thanks...

                          C Offline
                          C Offline
                          Christian Ehrlicher
                          Lifetime Qt Champion
                          wrote on 19 Nov 2023, 18:13 last edited by
                          #12

                          @mzimmers said in trying to understand smart pointers...:

                          What am I continuing to do wrong here?

                          You still use a QList - as I already told you QList needs a copyable type but std::unique_ptr<T> is not.

                          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                          Visit the Qt Academy at https://academy.qt.io/catalog

                          M 1 Reply Last reply 19 Nov 2023, 19:16
                          1
                          • C Christian Ehrlicher
                            19 Nov 2023, 18:13

                            @mzimmers said in trying to understand smart pointers...:

                            What am I continuing to do wrong here?

                            You still use a QList - as I already told you QList needs a copyable type but std::unique_ptr<T> is not.

                            M Offline
                            M Offline
                            mzimmers
                            wrote on 19 Nov 2023, 19:16 last edited by
                            #13

                            @Christian-Ehrlicher said in trying to understand smart pointers...:

                            QList needs a copyable type but std::unique_ptr<T> is not.

                            Ah, yes. And it appears that QScopedPointer is not either...pity.

                            So, if I use std::vector, and the make_unique that you mentioned above, I can modify what the unique_ptr references, and push it into the vector and it all works OK:

                            typedef std::unique_ptr<TestStruct> UniquePtr;
                            UniquePtr uniquePtr;
                            std::vector<UniquePtr> qVector;
                            
                            uniquePtr = std::make_unique<TestStruct>(myStruct);
                            
                            uniquePtr->i = 55;
                            qDebug() << uniquePtr->i;
                            qVector.push_back(std::make_unique<TestStruct>(*uniquePtr));
                            
                            uniquePtr->i = 555;
                            qDebug() << uniquePtr->i;
                            qVector.push_back(std::make_unique<TestStruct>(*uniquePtr));
                            
                            uniquePtr->i = 5555;
                            qVector.push_back(std::make_unique<TestStruct>(*uniquePtr));
                            
                            qDebug() << qVector.at(0)->i << qVector.at(1)->i << qVector.at(2)->i;
                            

                            Now: I want to reference elements in the vector, probably in a loop. Do I need to create a new unique_ptr for each loop iteration, since I can't do an assignment to it, or is there some other way to do this?

                            C 1 Reply Last reply 19 Nov 2023, 19:26
                            0
                            • M mzimmers
                              19 Nov 2023, 19:16

                              @Christian-Ehrlicher said in trying to understand smart pointers...:

                              QList needs a copyable type but std::unique_ptr<T> is not.

                              Ah, yes. And it appears that QScopedPointer is not either...pity.

                              So, if I use std::vector, and the make_unique that you mentioned above, I can modify what the unique_ptr references, and push it into the vector and it all works OK:

                              typedef std::unique_ptr<TestStruct> UniquePtr;
                              UniquePtr uniquePtr;
                              std::vector<UniquePtr> qVector;
                              
                              uniquePtr = std::make_unique<TestStruct>(myStruct);
                              
                              uniquePtr->i = 55;
                              qDebug() << uniquePtr->i;
                              qVector.push_back(std::make_unique<TestStruct>(*uniquePtr));
                              
                              uniquePtr->i = 555;
                              qDebug() << uniquePtr->i;
                              qVector.push_back(std::make_unique<TestStruct>(*uniquePtr));
                              
                              uniquePtr->i = 5555;
                              qVector.push_back(std::make_unique<TestStruct>(*uniquePtr));
                              
                              qDebug() << qVector.at(0)->i << qVector.at(1)->i << qVector.at(2)->i;
                              

                              Now: I want to reference elements in the vector, probably in a loop. Do I need to create a new unique_ptr for each loop iteration, since I can't do an assignment to it, or is there some other way to do this?

                              C Offline
                              C Offline
                              Christian Ehrlicher
                              Lifetime Qt Champion
                              wrote on 19 Nov 2023, 19:26 last edited by
                              #14

                              @mzimmers said in trying to understand smart pointers...:

                              Do I need to create a new unique_ptr for each loop iteration, since I can't do an assignment to it, or is there some other way to do this?

                              I don't understand - you already access the elements (via at() ) and therefore can call the functions of the object (or modify the members of your struct)

                              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                              Visit the Qt Academy at https://academy.qt.io/catalog

                              M 1 Reply Last reply 19 Nov 2023, 20:43
                              0
                              • C Christian Ehrlicher
                                19 Nov 2023, 19:26

                                @mzimmers said in trying to understand smart pointers...:

                                Do I need to create a new unique_ptr for each loop iteration, since I can't do an assignment to it, or is there some other way to do this?

                                I don't understand - you already access the elements (via at() ) and therefore can call the functions of the object (or modify the members of your struct)

                                M Offline
                                M Offline
                                mzimmers
                                wrote on 19 Nov 2023, 20:43 last edited by
                                #15

                                @Christian-Ehrlicher I'd like to be able to do the following:

                                for (int i = 0; i < list.size(); i++) {
                                    p = list.at(i);
                                	p.this = that; 
                                	p.the_other(); // etc
                                
                                C 1 Reply Last reply 19 Nov 2023, 20:53
                                0
                                • M mzimmers
                                  19 Nov 2023, 20:43

                                  @Christian-Ehrlicher I'd like to be able to do the following:

                                  for (int i = 0; i < list.size(); i++) {
                                      p = list.at(i);
                                  	p.this = that; 
                                  	p.the_other(); // etc
                                  
                                  C Offline
                                  C Offline
                                  Christian Ehrlicher
                                  Lifetime Qt Champion
                                  wrote on 19 Nov 2023, 20:53 last edited by
                                  #16

                                  Why do you want to assign something to the local variable p? What's the point?

                                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                  Visit the Qt Academy at https://academy.qt.io/catalog

                                  M 1 Reply Last reply 19 Nov 2023, 21:46
                                  0
                                  • C Christian Ehrlicher
                                    19 Nov 2023, 20:53

                                    Why do you want to assign something to the local variable p? What's the point?

                                    M Offline
                                    M Offline
                                    mzimmers
                                    wrote on 19 Nov 2023, 21:46 last edited by
                                    #17

                                    @Christian-Ehrlicher well, maybe I don't have to. The plan is to use this list in a list model I'm writing. I'll be making temporary variables of my struct, and copying to and from the list. (Plus QML access that I haven't even begun thinking about.) But...maybe I can do it all with newly-created unique_ptrs. I'll try and report back.

                                    BTW: should I consider the use of QScopedPointers instead?

                                    C Chris KawaC 2 Replies Last reply 20 Nov 2023, 05:38
                                    0
                                    • M mzimmers
                                      19 Nov 2023, 21:46

                                      @Christian-Ehrlicher well, maybe I don't have to. The plan is to use this list in a list model I'm writing. I'll be making temporary variables of my struct, and copying to and from the list. (Plus QML access that I haven't even begun thinking about.) But...maybe I can do it all with newly-created unique_ptrs. I'll try and report back.

                                      BTW: should I consider the use of QScopedPointers instead?

                                      C Offline
                                      C Offline
                                      Christian Ehrlicher
                                      Lifetime Qt Champion
                                      wrote on 20 Nov 2023, 05:38 last edited by
                                      #18

                                      Simply store the struct in the container.

                                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                                      Visit the Qt Academy at https://academy.qt.io/catalog

                                      1 Reply Last reply
                                      0
                                      • M mzimmers
                                        19 Nov 2023, 21:46

                                        @Christian-Ehrlicher well, maybe I don't have to. The plan is to use this list in a list model I'm writing. I'll be making temporary variables of my struct, and copying to and from the list. (Plus QML access that I haven't even begun thinking about.) But...maybe I can do it all with newly-created unique_ptrs. I'll try and report back.

                                        BTW: should I consider the use of QScopedPointers instead?

                                        Chris KawaC Offline
                                        Chris KawaC Offline
                                        Chris Kawa
                                        Lifetime Qt Champion
                                        wrote on 20 Nov 2023, 08:01 last edited by Chris Kawa
                                        #19

                                        @mzimmers said:

                                        I'll be making temporary variables of my struct, and copying to and from the list.

                                        The whole point of unique_ptr is that it is unique. It holds ownership of the object. You can't copy (temporary or otherwise) unique_ptr because then you would have two things owning the same object and that would just crash because of double delete.

                                        You can move unique_ptrs, because it moves ownership of the object, so only one pointer still owns the object.

                                        As others mentioned QList does not support move-only types because of implicit sharing. It needs to do copies underneath when a shared data detaches.

                                        QScopedPointer is just a simplified version of std::unique_ptr. Switching one to the other doesn't change anything.

                                        You can store unique_ptr in a std::vector, which does not do implicit sharing and supports move-only types:

                                        std::vector<std::unique_ptr<QString>> pointers;
                                        for (int i=0; i < 10; ++i)
                                        {
                                            pointers.push_back(std::make_unique<QString>("Hello!"));
                                        }
                                        

                                        or

                                        for (int i = 0; i < 10; ++i)
                                        {
                                            auto ptr = std::make_unique<QString>("Hello!");
                                            pointers.push_back(std::move(ptr));
                                        
                                            // ptr does not point to the object here anymore, it's been moved from.
                                            // Code below will compile but is invalid and will likely crash at runtime:
                                            ptr->isEmpty();
                                        }
                                        

                                        You can then access these pointers like this:

                                        for (int i = 0; i < 10; ++i)
                                        {
                                            bool use_the_string = pointers.at(i)->isEmpty();
                                        }
                                        

                                        or get a reference to the pointer:

                                        for (int i = 0; i < 10; ++i)
                                        {
                                            const auto& ptr_ref = pointers.at(i);
                                            bool use_the_string = ptr_ref->isEmpty();
                                        }
                                        

                                        but you can't copy them:

                                        for (int i = 0; i < 10; ++i)
                                        {
                                           // This won't compile. You can't copy unique_ptrs
                                            auto ptr_copy = pointers.at(i);
                                        }
                                        

                                        If you want to copy the object (not the pointer!) you can do it like this:

                                        for (int i = 0; i < 10; ++i)
                                        {
                                            QString string_copy = *pointers.at(i);
                                        }
                                        
                                        M 1 Reply Last reply 20 Nov 2023, 16:26
                                        3
                                        • M mzimmers
                                          19 Nov 2023, 18:08

                                          @Christian-Ehrlicher

                                          sigh I new I should have taken that extra C++ class in night school...

                                          OK, so I think I've added the move c'tor and move operator (though the docs are a little confusing; there's reference to a move assignment operator, which I'm not sure is the same thing). Code looks like this:

                                          struct TestStruct {
                                          	int i;
                                          	TestStruct() {}
                                          	TestStruct(TestStruct &ts) {i = ts.i;} // copy c'tor
                                          	TestStruct(TestStruct &&ts) { i = ts.i; } // move c'tor
                                          	TestStruct& operator=(TestStruct&& ts) { return *this; } // move operator
                                          };
                                          TestStruct myStruct;
                                          
                                          std::unique_ptr<TestStruct> *uniquePtr = nullptr;
                                          QList<std::unique_ptr<TestStruct>> list;
                                          uniquePtr = &myStruct; // how to form this?
                                          list.push_back(*uniquePtr); // how to form this?
                                          

                                          What am I continuing to do wrong here?

                                          Thanks...

                                          J Offline
                                          J Offline
                                          JoeCFD
                                          wrote on 20 Nov 2023, 16:20 last edited by JoeCFD
                                          #20

                                          @mzimmers said in trying to understand smart pointers...:

                                          uniquePtr = &myStruct; // how to form this?

                                          This is not allowed. myStruct sits in stack and will be cleared when your app runs out of its scope. However, uniquePtr will destroy it again when uniquePtr is not used anymore.

                                          1 Reply Last reply
                                          0

                                          8/30

                                          19 Nov 2023, 16:31

                                          topic:navigator.unread, 22
                                          • Login

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