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. move semantics

move semantics

Scheduled Pinned Locked Moved Unsolved C++ Gurus
6 Posts 3 Posters 1.3k 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.
  • K Offline
    K Offline
    Kent-Dorfman
    wrote on 2 Jul 2021, 04:56 last edited by
    #1

    I don't fully understand move semantics so my impression is that they are just a complicated abstraction designed to make c++ more "javaish".

    I think I get the fundemental idea but being someone who think in terms of how code looks after compilation and how it treats memory, I just don't understand.

    A guy corrected me today by stating "it's not the rvalue you are moving. It is a reference to the rvalue".

    OK...that's fine but something in the back of my brains says that is foolish.

    Ummm...a reference to a local stack variable or object becomes invalid when the current stack frame ends, so any reference to such an rvalue becomes a bug.

    Would love to see a concrete and well explained example of why/how to use move semantics...the geeks discussions I've read online don't make it any clearer to me.

    1 Reply Last reply
    0
    • C Offline
      C Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on 2 Jul 2021, 05:08 last edited by Christian Ehrlicher 7 Feb 2021, 05:10
      #2

      An example with std::vector:

      struct MoveMeIn
      {
        void moveMe(std::vector<char> &&data) {
          std::swap(data, m_data);
        }
        void copyMe(const std::vector<char> &data) {
          m_data = data;
        }
        void print() {
          std::cout << "ptr addr: " << (void*)m_data.data() << "\n";
        }
        std::vector<char> m_data;
      };
      ...
        std::vector<char> data1(10, '\0');
        std::vector<char> data2(10, '\0');
        std::cout << "data1: " << (void*)data1.data() << ", size: " << data1.size() << "\n";
        std::cout << "data2: " << (void*)data2.data() << ", size: " << data2.size() << "\n";
        MoveMeIn m;
        m.copyMe(data2);
        m.print();
        m.moveMe(std::move(data1));
        m.print();
        m.copyMe(data2);
        m.print();
        std::cout << "data1: " << (void*)data1.data() << ", size: " << data1.size() << "\n";
        std::cout << "data2: " << (void*)data2.data() << ", size: " << data2.size() << "\n";
      

      -->
      data1: 0x188c1b0, size: 10
      data2: 0x188c1d0, size: 10
      ptr addr: 0x188c600
      ptr addr: 0x188c1b0
      ptr addr: 0x188c1b0
      data1: 0x188c600, size: 10 <-- old pointer from m_data due to usage of std::swap()
      data2: 0x188c1d0, size: 10

      As you can see when data1 is moved, it's internal pointer is moved from data1 to m_data without doing a reallocation. Therefore you move the data from one object to another. No more magic. :)

      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
      6
      • J Online
        J Online
        jeremy_k
        wrote on 4 Jul 2021, 11:20 last edited by
        #3

        There's another aspect to move semantics that's unrelated to copy efficiency. Consider an object that represent an identity. Copying the object to create two instances might not make sense. Moving allows the instance to escape its original scope.

        My initial thought was to use QObject as the identity object example. That doesn't work as cleanly as I would like because QObject doesn't have a move constructor. std::thread does, which might event be better.

        Imagine:

        std::thread go()
        {
            std::thread threadOne([](){ while true printf("I'm alive\n"); };
            return threadOne;
        }
        
        void f()
        {
            std:thread threadTwo = go();
        }
        

        Does this code create two threads that spend all of their time proclaiming "I'm alive", or one thread that is created in go() but continues to exist in f()? std::thread's move constructor answers that question, reinforced by the lack of a copy constructor.

        Asking a question about code? http://eel.is/iso-c++/testcase/

        1 Reply Last reply
        0
        • C Offline
          C Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on 4 Jul 2021, 11:41 last edited by
          #4

          @jeremy_k said in move semantics:

          That doesn't work as cleanly as I would like because QObject doesn't have a move constructor. std::thread does, which might event be better.

          Another usecase is a std::unique_ptr.

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

          J 1 Reply Last reply 4 Jul 2021, 11:51
          1
          • C Christian Ehrlicher
            4 Jul 2021, 11:41

            @jeremy_k said in move semantics:

            That doesn't work as cleanly as I would like because QObject doesn't have a move constructor. std::thread does, which might event be better.

            Another usecase is a std::unique_ptr.

            J Online
            J Online
            jeremy_k
            wrote on 4 Jul 2021, 11:51 last edited by
            #5

            @Christian-Ehrlicher said in move semantics:

            @jeremy_k said in move semantics:

            That doesn't work as cleanly as I would like because QObject doesn't have a move constructor. std::thread does, which might event be better.

            Another usecase is a std::unique_ptr.

            Going back to the OP, std::unique_ptr may be the most universal and java-ish example.

            Asking a question about code? http://eel.is/iso-c++/testcase/

            1 Reply Last reply
            1
            • K Offline
              K Offline
              Kent-Dorfman
              wrote on 8 Jul 2021, 03:58 last edited by
              #6

              @Christian-Ehrlicher Appreciate the example. I understand the code you posted, but move semantics still kind of rub me raw. Maybe someday I'll drink the coolaid, but for now I'm comfortable with pointers and passing objects by reference.

              1 Reply Last reply
              0

              6/6

              8 Jul 2021, 03:58

              • Login

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