C++ 11: Rvalue Reference -- Move Semantics

Поделиться
HTML-код
  • Опубликовано: 24 янв 2025

Комментарии • 183

  • @daixtr
    @daixtr 2 года назад +15

    Compared to other C++ tutorials, this one clearly has the touch of a master.

    • @LowellBoggs
      @LowellBoggs Год назад

      absolutely, this is the best explanation that i have seen for this otherwise bizare concept. thanks!

  • @SomeoneCalledJoshua
    @SomeoneCalledJoshua 6 лет назад +13

    You, sir, have some of the clearest explanations of the complicated C++11+ examples I've seen - and I've read a lot of them. Thank you for taking your time to make these, I will recommend your channel to others learning C++.

  • @michaelcowan1761
    @michaelcowan1761 7 лет назад +7

    oh my god, thank you so much... this makes so much more sense than the 250 lines of code my textbook tried to use to explain this with shoddy prose.

  • @justinbroaddus8022
    @justinbroaddus8022 2 года назад

    Can we just acknowledge how much of a legend this guy is. These tutorials are honking good!

  • @andreashadjigeorgiou1596
    @andreashadjigeorgiou1596 4 года назад

    Thank god someone who explained the usage of move constructors without giving the example of push_back for vectors!

  • @dkdk9576
    @dkdk9576 4 года назад

    great tutorial, very clearly illustrated, much better than many so called professor.

  • @Gojam12
    @Gojam12 Год назад

    No kidding, this is the first time this made perfect sense to me, thank you sir. I subscribed to your channel

  • @davidutv
    @davidutv 6 лет назад +13

    Bo, I'm not sure if it was mentioned in the history of comments, but should you ever redo this (very nice) video, you might want to discuss copy elision. Some viewers may be at a loss to explain why their move constructor does not get called because the compiler is allowed to elude copying (darn smart compilers). Nice work though... Love your videos!

    • @linyoucheng1984
      @linyoucheng1984 6 лет назад +2

      lol, -fno-elide-constructors, it takes me a long while to figure this out.

    • @elliott8175
      @elliott8175 6 лет назад +2

      THANK YOU!! (and to Youcheng Lin also!)
      This was confusing the hell out'ta me!

    • @sino-atrial_node
      @sino-atrial_node 3 года назад

      If you are reading this, then also check out the requirement of copy elision on C++ 17

  • @AdalbertGeraldSoosaiRaj
    @AdalbertGeraldSoosaiRaj 8 лет назад +2

    Simple and clear explanation about move semantics! Thanks Bo! :)

  • @AJICams
    @AJICams 10 лет назад +148

    Good tutorial Bo. However, one mistake: the destructor here is not releasing all the memory in the array. It should be:
    ~boVector { delete [] arr_; }

    • @ChenHuang
      @ChenHuang 8 лет назад +5

      +AJICams I was wondering about that too, thanks for clearing that up!

    • @anandkulkarni2111
      @anandkulkarni2111 7 лет назад +1

      plus destructor should not delete if arr_ is nullptr ; i know it wont crash program but does not look sensible to delete a nullptr value.

    • @xeniakim2237
      @xeniakim2237 7 лет назад +9

      the delete shouldnt be much of a problem as the same amount of memory is being deleted and since double is a built in type, there will not be any memleaks. However, it is good practice to use delete[] if new [] was used. Also, a check to delete will be more costly so there is no need to do it.

    • @kocho4242
      @kocho4242 7 лет назад +13

      @Anand Kulkarni It's not needed to check if (nullptr == arr_) before delete [] arr_, because if arr_ is nullptr, then delete [] arr_ will do nothing.
      If we assume that mentioned destructor is called many times (let's say millions), then code without if (nullptr == arr_) will be faster.

    • @mayue6195
      @mayue6195 7 лет назад

      exactly.

  • @malharjajoo7393
    @malharjajoo7393 5 лет назад

    Excellent explanation:
    1) Explains what lvalue and rvalue are
    2) Explains what lvalue reference and rvalue reference are.
    3) Explains how they enable function overloading => they will also result in constructor overloading
    4) Introduces Move constructor (that will be called implicitly now instead of Copy constructor when dealing with rvalues)
    5)

  • @end_slavery
    @end_slavery 9 лет назад +4

    at 13:05, you say it is ok to call
    hoo(string s);
    no matter how big the string is. How? If I write
    string s = "askjo;sjedfselkajs;dlfijasdf";
    hoo(s);
    isn't a full copy being performed here?

    • @unvergebeneid
      @unvergebeneid 9 лет назад

      +fatichar Yep, my thought exactly. There's really no reason not to use const reference for objects whenever you can.

    • @zhimingwang2340
      @zhimingwang2340 8 лет назад

      Share the same point with you.. Bo needs to be more specific when making conclusions.

    • @kocho4242
      @kocho4242 5 лет назад +1

      I think it makes sense only in case you call it like this
      hoo(std::move(s));

  • @rapoliit
    @rapoliit 11 лет назад +1

    extremely good....invaluable listening.keep it up brother.

  • @arielspalter7425
    @arielspalter7425 5 лет назад

    I love your tutorials. They are clear and excellent paced.

  • @estebansalami6274
    @estebansalami6274 5 лет назад +1

    finally the video i was looking for !!!! u r my hero

  • @jonkrieger5271
    @jonkrieger5271 9 лет назад +5

    This was fantastically helpful, thanks Bo!

  • @abhishekkekre6395
    @abhishekkekre6395 5 лет назад

    The call to foo_by_ref at 8:55 does not work as we are trying to bind a rvalue to a reference which is not allowed by the compiler.

  • @yizhouluo9968
    @yizhouluo9968 Год назад

    9:06 foo_by ref() is accepting a reference, thus it expects an lvalue, createBoVector() will return an rvalue, in this case, shouldn't we have compile error ?

  • @DEMONminipro
    @DEMONminipro 6 лет назад +1

    After doing some trials with gcc I think that the behaviour of this code is very compiler specific
    foo(createBoVector()) at 06:00 does not call the copy ctor
    and after adding the move ctor at 08:00 it does not call it either

    • @linyoucheng1984
      @linyoucheng1984 6 лет назад +2

      add this compiler flag, -fno-elide-constructors, to remove the default optimization done by the compiler

  • @fondueeundof3351
    @fondueeundof3351 4 года назад

    @4:07: slightly offtopic, why don't we need to release the data that arr_ was (potentially) pointing to, at the beginning of the copy constructor, before we assign it a new array of doubles?

  • @thestarinthesky_
    @thestarinthesky_ 2 года назад +1

    @ 8:57 , I think it should have been: foo_by_value(createBoVector()) and foo_by_ref(reusable) , can't bound an r-value to l-value reference!

  • @floatoss
    @floatoss Год назад

    Hey Bo, shouldn't the signature of the foo_by_ref function be "foo_by_ref(const boVector& v)", as the standard says that rvalues can only be bound to const references? Timestamp being 9:02. Thank you!

  • @aquasaiyan7877
    @aquasaiyan7877 3 года назад

    awesome video. I"ve been learning cpp b/c of the new work. And lots of nuances that I need to learn from a java background.

  • @AnilUpadhyayMEE
    @AnilUpadhyayMEE 2 года назад

    Thanks a lot for such excellent content with a beautiful explanation. Kindly share other latest versions too.

  • @gabgaby999
    @gabgaby999 6 лет назад +1

    Good explanations on the move semantics ! Thank you !

  • @LS-cb7lg
    @LS-cb7lg 3 года назад

    this video was an ablosute eye opener! thank you so much :)

  • @Kromush1995
    @Kromush1995 5 лет назад

    At 6:27 (it's even earlier, but this is when my question occured): Why would we want to use a move constructor, when we could just make the foo() function to accept the boVector object as a const &?

    • @rae4652
      @rae4652 5 лет назад

      Probably late to this, but in that case, foo() will modify the boVector, so it can't be const and then you would just be taking an lvalue reference.
      Here's a short overview as far as I understand it:
      value: Copy the parameter into a temporary variable which gets destroyed after the function ends
      reference: Take an lvalue by reference - values can not be used as a parameter
      const reference: Take both lvalues and rvalues as references. However since they are const, neither can be modified later on
      Rvalue reference: Can take rvalues by reference and modify them
      Hope I could clear up confusion :D

  • @KayOScode
    @KayOScode 5 лет назад +2

    I have always just used const references
    but I might be able to find a use for this, I just don't see any reason to force it's use in my code

  • @meer_kat5158
    @meer_kat5158 3 года назад +1

    Hello @6:45 the destructor must have delete arr_ [] instead of delete arr_

  • @21kalee
    @21kalee 5 месяцев назад

    foo_by_value and foo_by_ref are marked incorrectly in the video @8:51 time.

  • @hdeng1566
    @hdeng1566 4 месяца назад

    Best explanation, Thanks God! Pls make more vedioes

  • @tarasmorozovsky1703
    @tarasmorozovsky1703 10 лет назад +38

    class boVector should have destructor with "delete [] arr_;" statement instead of "delete arr_;" as you use "new[]" but not "new" to allocate memory.
    and its size shold be represented by a variable of type size_t instead of int :(
    nice explanation of move semantics though

  • @bunc11
    @bunc11 8 лет назад +15

    am... destructor should be delete [ ] arr_; right?

    • @AdrianYang
      @AdrianYang 8 лет назад +2

      +bunc11 I think both delete arr_ and delete [] arr_ are OK, because the type of arr_ is double*, although delete [] arr_ is better.

    • @MarcusAseth
      @MarcusAseth 8 лет назад +2

      #Adrian Yang they are not both ok, if you call delete without square brackets you are only deleting the first element pointed by the double* which corresponds to arr_[0], instead of deleting the whole array, thus delete[] is the only right way to avoid a memory leak in your program (or even better, smart pointers)

    • @Alex_ssss
      @Alex_ssss 7 лет назад

      right, new - delete, new[] - delete []

    • @Ben-os7if
      @Ben-os7if 6 лет назад

      I tried deleting an array on Ubuntu and valgrind shows no resource leak. So they should be both fine.

    • @yukewang1832
      @yukewang1832 5 лет назад

      @@Ben-os7if It's an undefined behavior tho

  • @denomycor3758
    @denomycor3758 5 лет назад

    8:56 wait how can foo_by_ref(createBoVector()) work if it takes an lvalue ref. and createBoVector() is an rvalue?

    • @fredwu6812
      @fredwu6812 5 лет назад

      Yes, you are right. fuck him

    • @tianhepeng9162
      @tianhepeng9162 5 лет назад

      @@fredwu6812 But you don't have to be so rude.

  • @liveonphoenix5045
    @liveonphoenix5045 2 года назад

    How does this syntax being ok? "rhs.arr_ = nullptr", while before hand the pointer "arr_ = rhs.arr" is pointing to it?

  • @m1ch3lr0m3r0
    @m1ch3lr0m3r0 2 года назад

    Thanks for this videos! Unitl now I was creating move constructors like it was alchemy

  • @Pupperoni938
    @Pupperoni938 Год назад

    Very nice explanation. Thanks.

  • @-taz-
    @-taz- 6 лет назад +1

    13:04 Old Transformers cartoon on in the background.

  • @toni9305
    @toni9305 3 года назад

    Great video

  • @raminkord8334
    @raminkord8334 4 года назад

    Thank u for your clear explanation, it was very educational.

  • @juniorsilva5713
    @juniorsilva5713 Год назад

    Thank you! Great explanation!

  • @johnsnow9925
    @johnsnow9925 8 лет назад +4

    When you assign 'nullptr' to rhs.arr_, doesn't that mean that the rhs object will remain in the memory?

    • @bechone100
      @bechone100 7 лет назад +8

      Yes. Because it need to be used by the function foo, and it will be destroyed after foo function ends

  • @zhimingwang2340
    @zhimingwang2340 8 лет назад +4

    binding rvalue to lvalue reference will cause compile error. should use const lvalue reference.

  • @Gerald-iz7mv
    @Gerald-iz7mv 10 лет назад +2

    rhs is a lvalue in boVector(boVector&& rhs) ?

  • @totolanouille
    @totolanouille 4 года назад

    With g++ passing a rvalue will perform a copy elision. So we need to disable copy elision in order to see a move constructor called.

  • @huangxf
    @huangxf 8 лет назад

    A funny thing I just found is, if I add cout in both copy an move constructor for this code, in gcc 4.8, there's no move constructor message printed, but in MS VS2010 compiler, move constructor message printed

  • @musicfan1695
    @musicfan1695 4 года назад

    good video, very well explained

  • @padamgurung7112
    @padamgurung7112 6 лет назад +1

    lvalue is simply locator value, i.e. an object that can be located in the memory. And, rvalue is register value which is computed and the result is placed in some register temporarily in CPU. So, rvalue is such an object which cannot be located in memory

    • @HomoSiliconiens
      @HomoSiliconiens 6 лет назад +1

      Your explanation is 99 percent correct, but still 1 percent is missing. glvalue, lvalue, xvalue, prvalue, constant expression, volatile, and lots of other advanced C++ constructs are simple and crystal clear if we look them from the Assembler language level.
      Since C++ Standard Committee are trying to explain a certain concept in C++ to non Assembler language programmers, they have to make up weird terminologies, such as glvalue, xlvalue, prvalue, even constant expression... unevaluated expression. All these concepts in C++ are trivial and do not need any explanations in Assembler language level. Anyone who has some experience in programming using Assembler language can readily understand what all weird terminologies are saying.
      C++ language is advancing both in high-level and low-level constructs.

  • @boyuanli7843
    @boyuanli7843 4 года назад

    Clear and clean. Thank you!

  • @littlee300
    @littlee300 8 лет назад +1

    Very Nice tutoriar.

  • @chengliangyu5672
    @chengliangyu5672 6 лет назад

    Thank you for making the video. I learned a lot from it.

  • @jankinsics
    @jankinsics 9 лет назад

    very nice video. Thanks so much. Clear some doubts of mine.

  • @pauliewalnuts6734
    @pauliewalnuts6734 7 лет назад

    bo you are an amazing teacher keep up the good work!

  • @EricOuellet2
    @EricOuellet2 5 лет назад

    Great Video! I understand a lots with you. Thanks so much! (Not important but just mention that I agree with Taras)

  • @AlexDC93
    @AlexDC93 10 лет назад +1

    How are you accessing rhs's private pointer variable arr_ from the move constructor?
    I though another objects private variable should not be accessible, or is this something to do with it being a rvalue?
    I'm new to c++, used to java so that might be why i am confused.
    Any answers are welcome, thanks.

    • @aleksaristic1773
      @aleksaristic1773 10 лет назад +2

      In c++ every class method (function) has access to private fields (of the same class).
      Constructor is just one of the class methods.
      One more thing: access rights in c++ refers to classes, not the specific objects.
      Heard that in Java access rights is limited only to objects.

    • @huangxf
      @huangxf 8 лет назад

      No you can't access an modify the value of rhs.arr_ , it's a mistake

    • @vuu6aa0Waiyaish4
      @vuu6aa0Waiyaish4 6 лет назад

      Yes you can. I even just tried it.

  • @JuddNiemann
    @JuddNiemann 7 лет назад

    Good explanation of move semantics.

  • @BartomiejWok
    @BartomiejWok 7 лет назад

    Excellent explanation of this not so easy to understand topic.

  • @VadixeM
    @VadixeM 6 лет назад

    8:00 move constructor will not be called. I've tried it myself.

    • @kocho4242
      @kocho4242 5 лет назад

      Please try to compile the code with -fno-elide-constructors option. Move constructor will be called then.

  • @shawnshaw9859
    @shawnshaw9859 2 года назад +1

    Would be wonderful to upgrade this series to c++20

  • @SrIgort
    @SrIgort 5 лет назад

    I have one question, is this useful when you have static arrays?

  • @d.dineshkumarreddy2922
    @d.dineshkumarreddy2922 2 года назад

    Can anyone please explain me how constructor is calling with the function calling ?

  • @gatoradeee
    @gatoradeee 7 лет назад

    Thank you. This helps tremendously. 10/10

  • @29srinath
    @29srinath 8 лет назад +1

    Hi. I have a question.
    I can use the lvalue reference and do the same (in constructor). Move the object. So why do we need special rvalue reference in your use case?

    • @pradeepreddy175
      @pradeepreddy175 8 лет назад

      I think the function call would be ambiguous then.

  • @mailtomemailtome
    @mailtomemailtome 10 лет назад

    minor correction the signature of foo_by_ref has to be 'const boVector&' , thats fine as focus here is on move constructor.

    • @jeremyley7031
      @jeremyley7031 9 лет назад

      Why must it be const? I see this everywhere but don't understand why it must be immutable.

    • @MajorBreakfast
      @MajorBreakfast 9 лет назад

      +Jeremy Ley Two reasons:
      1. It's a stricter contract. The function tells you that it won't mutate the object just by its signature.
      2. If your value is already const, then you're still allowed to call this function. If it expected a mutable reference then you'd need to use an ugly `const_cast(val)` to remove the constness.
      You should always add const to your references (unless you really mutate). So, james k really should say "should" not "has to".

  • @Carlos-sy7cv
    @Carlos-sy7cv 7 лет назад

    Can someone explain to me how the foo function actually applies the constructor to the class object parameter? I don't see a connection between the foo function and the constructors he included.

    • @Dziaji
      @Dziaji 7 лет назад

      It is because the bovector is being passed by value. When you pass by value, the parameter is its own separate instance of the object. The compiler will automatically call an object's copy constructor when passing by value so that the parameter object has the same data of the object that was passed to the function.
      If you pass by reference, no copy needs to be made, so the compiler will not call the constructor.

  • @Abdullah-mg5zl
    @Abdullah-mg5zl 10 лет назад

    Excellent explanation Bo, thanks!

  • @kpopisthebestful
    @kpopisthebestful 5 лет назад

    Why not just use pass by const reference instead of the move semantics?

  • @altafmahmud6095
    @altafmahmud6095 7 лет назад

    At 04:08, usually when you allocate memory with "new []" then you should use "delete []" operator, is there any chance of memory leak in this code?

  • @longgong5061
    @longgong5061 8 лет назад

    Hi Bo Qian, your explanation is very clear. However, how do I really know which constructor is called?
    I have tried to add a printing sentence in each constructor (i.e.,
    copy constructor and move constructor). However, when I am passing by a lval, the printing message (in the copy constructor) is printed, while if I passed a rval, no message is printed.

    • @matthiasherrmann3420
      @matthiasherrmann3420 7 лет назад

      For that use debugging, set a breakpoint and step through the code.

  • @nsv.2344
    @nsv.2344 8 лет назад

    when we use rhs.arr_ = nullptr; it doesn't delete the elements in heap? Dont we have to use delete rhs? and then assign nullptr to rhs.arr_?

  • @cordialbadger4724
    @cordialbadger4724 9 лет назад

    First, thank you for making these videos. I have found them to be beneficial.
    You mentioned that the the STL container use the move semantics. You gave an example of a function returning a vector by value. Since we already have Return Value Optimization, is there an advantage to using the move semantics? Should I use move semantics for my own objects rather than relying on RVO?

    • @cordialbadger4724
      @cordialbadger4724 9 лет назад

      +Peterolen Thanks make sense. Thank you for the reply.

  • @drfpslegend4149
    @drfpslegend4149 4 года назад

    Fucking fantastic explanations my dude, I'm super glad I found your video :)

  • @prashanthg7619
    @prashanthg7619 9 лет назад

    Very nice video. Thanks !!

  • @sushrut24
    @sushrut24 8 лет назад

    In boVector size is a private variable...how can you do rhs.size in the copy constructor

    • @turtlemasterroshi
      @turtlemasterroshi 8 лет назад +2

      It is private to the class 'boVector' not to the object 'rhs'

  • @BertvanderWeerd
    @BertvanderWeerd 11 лет назад

    Great video, again:)

  • @AbdulelahAlJeffery
    @AbdulelahAlJeffery 7 лет назад +2

    it would've been better if you replaced the boVector example with a *working* one.

  • @Hilian86
    @Hilian86 5 лет назад

    How would you implement those functions?

  • @agnichatian
    @agnichatian 8 лет назад

    Nicely done.

  • @ldxyz-s1e
    @ldxyz-s1e 7 лет назад

    2:16
    std::move() converts lvalue to rvalue.
    12:53

  • @K-vdE
    @K-vdE 8 лет назад +10

    the destructor of boVector should call 'delete[] arr_', not 'delete arr_'.

  • @raghul1208
    @raghul1208 2 года назад

    excellent

  • @ddastoor
    @ddastoor 6 лет назад

    thanks a lot Bo !!!

  • @arjun5j
    @arjun5j 8 лет назад

    Thank you very much!!

  • @weili5342
    @weili5342 6 лет назад

    where can I download the ppt?

  • @nickchen8259
    @nickchen8259 8 лет назад

    Excellent

  • @JoffreyB
    @JoffreyB 6 лет назад +1

    you could pick another name for variable 'a'. Its kinda confusing when you writing two 'a' in comment section.

  • @yahortsaryk2842
    @yahortsaryk2842 7 лет назад

    great ,thanks !

  • @mastermati773
    @mastermati773 2 года назад

    This tutorial is fucking great.

  • @yuqingwang7375
    @yuqingwang7375 5 лет назад

    You should really run your code time to time to show that it is working. In my code, both foo methods called copy constructor.

  • @sleepyNovember_project
    @sleepyNovember_project 11 месяцев назад

    9:46 хехееее distroy 😊

  • @brunoccs
    @brunoccs 11 лет назад

    Wouldn't it be easier to just use pointers?

    • @daggawagga
      @daggawagga 9 лет назад +1

      Bruno Carlos Caetano Santos .
      Pointers are evil mmmkay?

    • @chikaboom5951
      @chikaboom5951 9 лет назад +1

      ***** no

    • @daggawagga
      @daggawagga 9 лет назад

      chika boom ok

  • @malharjajoo6237
    @malharjajoo6237 7 лет назад +1

    lost me after 8:00

  • @balygaby
    @balygaby 4 года назад

    It's hard to talk about this when you can't pronounce R nor L

  • @baranidharankaruppusamy4519
    @baranidharankaruppusamy4519 5 лет назад +1

    For anyone need refresher on rvalue and lvale, here is link to video by Bo Qian
    ruclips.net/video/UTUdhjzws5g/видео.html

  • @salex2500
    @salex2500 9 лет назад +1

    say what again? lvalue leflence

    • @unvergebeneid
      @unvergebeneid 9 лет назад +10

      +salex2500 The only embarrassing thing here has been said by you.

    • @xriccardo1831
      @xriccardo1831 6 лет назад

      salex2500 are you stupid?

  • @luciojb
    @luciojb 5 лет назад

    How to goal kick lmao

  • @carnaqe1154
    @carnaqe1154 Год назад

    its not very good to give such a poor written Codesnippet where you do not explain the function signatures which are very much needed to understand this topic. Bad tutorial.

  • @charoniv5631
    @charoniv5631 3 года назад

    You sound like erchito