Introduction to std::move in C++ | Modern Cpp Series Ep. 32

Sdílet
Vložit
  • čas přidán 3. 06. 2024
  • ►Full C++ Series Playlist: • The C++ Programming La...
    ►Find full courses on: courses.mshah.io/
    ►Join as Member to Support the channel: / @mikeshah
    ►Lesson Description: In this lesson I am going to talk to introduce std::move and the idea of move semantics. Move semantics allows us in modern C++ to transfer ownership (i.e. steal a resource) from one object to another. This allows us to avoid copies when we truly want to transfer a resource. The implications of this, is that we can potentially increase performance, when we want to transfer ownership, and then avoid unnecessary copies.
    ►CZcams Channel: / mikeshah
    ►Please like and subscribe to help the channel!
  • Věda a technologie

Komentáře • 45

  • @cameronrowe2032
    @cameronrowe2032 Před 7 měsíci +8

    Two hours of awkwardly delivered obfuscating lecture in college, or 10 minutes with Mike - take your pick! Excellent explanation, as usual, Dr. Shah. Thank you!

  • @tim4857
    @tim4857 Před 9 měsíci +2

    So here the std::move here equals to static_cast, which means that the move semantic doesn't "move" the resource, it just converts the lvalue to an rvalue.
    The implementation of the move assignment operator actually "steals" the resources held by "myString".

    • @MikeShah
      @MikeShah  Před 9 měsíci +1

      Correct, I should more explicitly state that around the 5:50 mark or so that 'std::move' is not really doing anything other than the cast as you say which allows us to call a function that takes as a parameter an rvalue reference (and within that function the 'resource stealing' takes place).

  • @dogdog5994
    @dogdog5994 Před 2 lety +3

    I'd love to see more videos for WxWidgets, an in-depth series about WxWidgets, basically.
    An in-depth series about creating GUI win32 apps in C++ and C would be interesting as well. It's hard to find good videos about it on youtube. The message loop and the processing of messages is interesting. Modern WinForms and to a lesser degree WPF apps are wrappers around the win32 GUI which makes it relevant for learning those too.

    • @MikeShah
      @MikeShah  Před 2 lety +2

      Noted! I have a few videos on wxWidgets. Will certainly be adding to this playlist

  • @VoidloniXaarii
    @VoidloniXaarii Před rokem +2

    Thanks a lot again. This did indeed make move semantics just a little bit less scary

    • @MikeShah
      @MikeShah  Před rokem +1

      Cheers, you are most welcome!

  • @oscarmvl
    @oscarmvl Před rokem +1

    Very clear example! Thank you.

    • @MikeShah
      @MikeShah  Před rokem +1

      Cheers, thank you for the kind words!

  • @dhanushs1802
    @dhanushs1802 Před rokem +1

    Very well explained as always. Thank you.

    • @MikeShah
      @MikeShah  Před rokem

      Cheers thank you for the kind words

  • @djsixottawa
    @djsixottawa Před 3 měsíci +1

    Thanks for the crystal clear explanation! :)

  • @_ndot
    @_ndot Před rokem +3

    Hi, first of all thanks for the tutorials, been learning a lot.
    Regarding the move, I also thought this did some switcheroo with pointers but it seems its not always the case at least for std::string.
    After looking at the standard library and getting my eyes crossed, it seems a lot of the times the memory is just copied, and the first byte of the old memory is zeroed out.
    e.g.
    int main()
    {
    std::string s1 = "hello";
    char* s_p = s1.data(); // Pointer to data
    std::cout

    • @MikeShah
      @MikeShah  Před rokem +1

      I did a quick look, and it looks like it's doing the move. A pointer (underlying data) is only 8 bytes, so you're seeing the first byte swapped. It just so happens that the address is zero in that example it appears. Underlying data (e.g. size) looks likely also being updated, or otherwise size may not get updated until a write (e.g. copy on write).

    • @donaldslowik5009
      @donaldslowik5009 Před 2 měsíci

      You have to update s_p after the move from, and look at pointers, not their addresses:
      std::string s1 = "hello";
      char* s_p = s1.data(); // Pointer to data
      std::cout

  • @dadlord689
    @dadlord689 Před 6 měsíci +1

    If I'm understanding it correctly - move is stack specific thing (deals with functions inner scope parameters recopying problem).

    • @MikeShah
      @MikeShah  Před 6 měsíci +1

      Not necessarily stack specific, but could in fact 'steal' the ownership of an inner scope to some other outer scope object.

    • @dadlord689
      @dadlord689 Před 6 měsíci

      @@MikeShah In the scope of execution flow as I get it. I have figured out that variables (stack allocated bits of data) - can be cast to rvalue and this will allow to assign their value to something else on this stack (a variable of the same type or a field of a struct). And by struct I mean a complicated data type yet allocated on stack (not heap). But once the data is written within a field of an object that is allocated on heap - you won't be able to move it anywhere. And so in my opinion this concept of move is just badly implement in the language, causing frustration. So technically I think it would be fair to say that move is possible only within stack mamory (as any function is called on stack allocating it's parameters on it, yet allowing to intake an rvalue of something from the outer, relative to this function, scope {this thing} ).

    • @dadlord689
      @dadlord689 Před 6 měsíci +1

      As a representative of the pure frustration I have concluded the next: I believe that move operation is possible within CPU cache where anything from heap should be copied into (from RAM) in order to be rad or modified. And after that - result will be copied back to RAM (if modification occured). And so I guess that move operation is happening within CPU cache. And so I see the ram as a grid of bits. Only grid owns values in it's cells, so there is no spoon, Neo (there is no fields ownership concept in hardware). But it reminds me ECS where entity is just referencing (own) bunch of components while represents just an integer identifier. And so move should prevent non needed copy of an object that haven't left CPU cache stack yet. Anyway it looking to be a feature that will take time to realize.

  • @crazymemes4080
    @crazymemes4080 Před měsícem +1

    Mike does this move only work's for strings? Can i move a vector of number to another vector?

    • @MikeShah
      @MikeShah  Před měsícem

      Move works for vectors and many other containers. Only if the container says non-moveable (i.e. move operator has been =delete()) is it not possible :)

  • @herrdingenz6295
    @herrdingenz6295 Před 3 měsíci +1

    you forgot to mention one very important thing ... std::move doesn't always move .. sometimes it is forced to make a copy, like here:
    void some_function(const DataType& some_data)
    {
    auto temp = std::move(some_data);
    }
    this will actually copy some_data instead of moving it, even though it was given to the function by const reference ... and exactly there is the problem: you can't std::move const objects - that will always result in a copy

    • @MikeShah
      @MikeShah  Před 3 měsíci

      Cheers--another good piece of information!

  • @tim4857
    @tim4857 Před 9 měsíci +1

    Thanks

  • @asliddinkhud
    @asliddinkhud Před 7 měsíci +1

    Hallo, thanks for nice tutorials first of all. I am learning a lot.
    I tried this move semantics for int variables and it did not work as it is. First initialized variable did not loose its value. So this operation works well for string only?

    • @MikeShah
      @MikeShah  Před 7 měsíci +1

      For primitive types I would not expect anything to change -- meaning there's no data on the heap. If you allocate a single pointer to an integer however, the pointer should move. 🙂

    • @DhananjaySingh-po2uc
      @DhananjaySingh-po2uc Před 3 měsíci

      I believe it works only for the object which implements overloaded move assignment operator. So it works for string,vector types but not for primitive types

  • @k0185123
    @k0185123 Před 3 měsíci

    Nice!!!! But I don't really understand how that static_cast(mystring) works. Does it mean the type of "mystring" is converted into the rvalue reference std::string&&? If so, why does "myString" become empty after the assignment?

    • @MikeShah
      @MikeShah  Před 3 měsíci +1

      static_cast(myVariable) is effectively the same as std::move, but std::move documents exactly what you want do (to return an rvalue reference). myString becomes empty because we are 'stealling the resource' away when we assign it elsewhere. This is a way of programming where you only have one unique owner of data.

    • @k0185123
      @k0185123 Před 3 měsíci +1

      @@MikeShah I see! Thank you for the clarification :)

  • @__hannibaal__
    @__hannibaal__ Před rokem +1

    Hello ;
    It s just hint :
    If we have two object OBJ1 { heavy resource }; and OBJ2 {};
    Instead to move these resource so why not just move the named object OBJ1 OBJ2; or move only reference address ;…. ???

    • @MikeShah
      @MikeShah  Před rokem

      std::move is effectively doing that move of resources.

    • @__hannibaal__
      @__hannibaal__ Před rokem +1

      @@MikeShah Yes 👍; i still digging deep and deep in structure of C++; and how it made thing so beautiful. Thanks mike for your help.

    • @MikeShah
      @MikeShah  Před rokem

      @@__hannibaal__ Cheers!

  • @teluguanimetoon2811
    @teluguanimetoon2811 Před 4 měsíci +1

    hi mike i'm big fan of you l like your videos
    i used this function fun() two different ways below
    #include
    void fun(std::string &&dummy){
    dummy+="shaik";
    }
    int main() {
    std::string s="azeem";
    fun(std::move(s));
    std::cout

    • @MikeShah
      @MikeShah  Před 4 měsíci

      I think this is working as expected, Consider the string 's' that you are passing in both cases is appending a string literal to the string. 'dummy' passed by reference in the second case makes sense that this is doing an append. In the first case, += is merely allocating space for the additional 'shaik' and appending it to the storage, there's no real change in ownership here.

    • @teluguanimetoon2811
      @teluguanimetoon2811 Před 4 měsíci

      @@MikeShah thanks for the replay can you please make a video on semaphores

    • @MikeShah
      @MikeShah  Před 4 měsíci

      ​@@teluguanimetoon2811cheers! Have you seen my other concurrency videos? Perhaps I can add for semaphores, latches, etc.

    • @teluguanimetoon2811
      @teluguanimetoon2811 Před 4 měsíci

      @@MikeShah I have seen those videos, and suggested to so many friends. Waiting for new videos

    • @MikeShah
      @MikeShah  Před 4 měsíci

      @@teluguanimetoon2811 cheers!

  • @my4127
    @my4127 Před 6 měsíci

    5:50