Move Semantics in C++

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

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

  • @TheCherno
    @TheCherno  4 года назад +237

    Hope you all enjoyed the video! This is just the beginning of the Move Semantics Saga™, still to come is std::move, the move assignment operator, and more! Thanks for watching! ❤️
    P.S. RELAX GUYS THE PS5 PART 2 VIDEO IS COMING TOMORROW

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

      Do you have your own personal library of functions, classes, namespaces, etc? My professor told me that it's important for programmers to have their own tools which make their own methods easier.

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

      ok

    • @platinoob__2495
      @platinoob__2495 4 года назад +1

      Excuse me, I know this is out of the point, but, do you know a way to turn off auto save in Visual Studio Community 2019?

    • @pratikpatil1383
      @pratikpatil1383 4 года назад +1

      Thanks for starting with Move Semantics.. looking forward for more about this..👍

    • @shaiavraham2910
      @shaiavraham2910 4 года назад +1

      Can you make a video about the rule of 3 and the rule of 5 and how to implement them properly?

  • @shah.kairav
    @shah.kairav 3 года назад +150

    In case anyone is wondering why there is only one "Destroyed" line being printed on Cherno's terminal, remember that his program halts due to "std::cin.get()". Once he presses Enter, he should see the other "Destroyed" message.
    Reason for two destroys: 1 where the hollow object is destroyed + 1 where the actual heap memory is deallocated.
    Hope this saves time for someone and helps!

    • @Mzkysti
      @Mzkysti 3 года назад +5

      Thanks, I was getting two "Destroyed" and was like what the heck ;). Then I debugged it and the first one is destroying object with size of 0 and data as null, so I actually deduced this somehow myself too...

    • @pnuema1.618
      @pnuema1.618 2 года назад

      yeah I was wondering! saved me some time!

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

      Bless your soul...

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

      it helps! should read the comment first before figuring it out myself🤣

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

      Thank you very much for your comment! I was confused by the two destructors. But now I know that happens)

  • @justman7656
    @justman7656 6 дней назад

    I truly love your channel, man
    I read a bunch of internet articles and watched couple of videos and NO ONE made it that clear and consistent way
    Thank you so much, i finally understood this stuff

  • @Norhther
    @Norhther 4 года назад +85

    8:24 noexcept is important for performance reasons. In a talk I saw, the example presented was 60% faster using noexcept because of the nature of push_back operation in std::vector. So keep that in mind!

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

      what's the talk you saw? :)

    • @torstein5
      @torstein5 Год назад +13

      @@IndyR0ck Probably this one: Back to Basics: Move Semantics (part 1 of 2) - Klaus Iglberger - CppCon 2019

    • @IndyR0ck
      @IndyR0ck Год назад +3

      @@torstein5 thx!

  • @TiredLemonpie
    @TiredLemonpie 4 года назад +11

    I owe you a huge thank you ! I've been trying to understand what are lvalue and rvalue for quite a long time, and an even longer time for what the move semantic was all about, and I've finally understand it with your video.
    I'm in a big learning phase right now, and your channel is an awesome way to improve myself. Thanks for the good work !

  • @nabeelsherazi8860
    @nabeelsherazi8860 3 года назад +8

    Holy shit. I thought I knew things. I don’t know anything. This channel has been such a blessing. Instant sub.

  • @alextiga8166
    @alextiga8166 4 года назад +95

    This C++ series will never run out of topics to make a video about :)
    I've got too many requests what to cover in next videos.
    For example Multithreading: it would take forever to make videos about threads, locks, lock-free synchronization, fibers, coroutines etc.

    • @godnyx117
      @godnyx117 4 года назад +8

      This didn't aged well...

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

      ​@@godnyx117 Oh yeah I expected this series to cover more advanced topics but had to do my own research on the topic instead.
      Still a very great series and the best C++ series there is on RUclips!

  • @toddwasson3355
    @toddwasson3355 2 года назад +6

    Thank you so much for this move semantic vid. This has been wildly helpful to me today. Love your channel, your C++ playlist is by far my favorite of all C++ content.

  • @Yupppi
    @Yupppi Год назад +4

    Some of the videos are really clear cut and understandable, but I must say that in this one I dropped the ball very quickly. In like 10 seconds there appeared 50 lines of code and multiple class with their methods, privates, publics, printf, memcpy, delete etc.

  • @iiTzLamar
    @iiTzLamar 4 года назад +381

    m_Data = new char[m_Size] should be freed with delete [ ] m_Data; and not delete m_Data;

    • @gideonunger7284
      @gideonunger7284 4 года назад +16

      It should also be m_Size + 1 when allocating for the null terminator

    • @Spirrwell
      @Spirrwell 4 года назад +57

      @@gideonunger7284 Not necessarily. You don't need to store a null terminator if you know your string's size. Though it can be useful with C style string functions.
      But he should've used delete[] or maybe even allocated with a unique_ptr instead.

    • @txorimorea3869
      @txorimorea3869 4 года назад +14

      That is good advice in general, however in this case is not necessary because the destructor of char is a no-operation. In this specific scenario is not necessary to call the destructor of every object in the array by calling delete[].

    • @gideonunger7284
      @gideonunger7284 4 года назад +1

      @@Spirrwell yes sure if you don't work with any c string functions or pass that pointer to the outside it's fine. But it's still dangerous in c++ since the assumption of a char* is that it's null terminated. Rust doesn't use null termination but there it's the standard of the language so it's not a problem anywhere

    • @TheJackiMonster
      @TheJackiMonster 4 года назад +6

      @@gideonunger7284 It's already dangerous to assume the const char* passed to strlen() will be null terminated. In C++ a compiler might add a null character to such values in double quotes but a C compiler won't do that implicitly which makes sense because you will know the length of a constant array of chars in your code already as developer.

  • @ericprincen3345
    @ericprincen3345 3 года назад +17

    My first professional language was C++, and I moved from it in 1998 when I started working in Internet / Social media. I've moved back to writing low level code on hardware again, and I've been enjoying your videos a great deal. C++ has come a long way, and you've made my transition back a very easy one.
    BTW, I love the Hazel stuff too. Last time I worked with 3D graphics was when bsp trees were a new thing (and "fingering John Carmack" was something that was regularly done...) Fun to see how far that has all gone. I'm not doing any graphics right now, but fascinated with amount of forward movement in the field over the past 25 years.

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

      Pointing fingers at sir John Carmack? Sounds like the DOS days to me!
      I'm sorry I'm asking this _TWO_ years later, but in your opinion, how fast is C++ at evolving?
      It is often called an ever-evolving language, and especially with us getting a new standard every third year, I, a beginner, feels the same way.
      Thoughts?
      I invite other veterans to answer, too!

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

    This makes way more sense than what was being taught to me, where we just pushed multiple of the same object into a vector with different values (i.e. vec.push_back(Move{10})... vec.push_back(Move{n})). Sure it works, but doesn't help with visualizing the need to use a move constructor or semantics. This video helps so much, it just clicked instantly after watching this!

  • @Albert-lr7ky
    @Albert-lr7ky 2 года назад +18

    Very nice and excellent video!!! Tho I've got a small question: should we be usong "delete [ ] m_Data" in the destructor? Since it is created from "new [ ]"

    • @jamesbaguio2386
      @jamesbaguio2386 Год назад +3

      Yes, the program needs to clean the continuous block of memory allocated to m_Data.

  • @aqezzz
    @aqezzz 4 года назад +2

    Thank you for this video! This is one of my favorite series on RUclips and this is a topic that can be quite confusing but you simplified it beautifully. Great job and keep up the good work

  • @JayAnAm
    @JayAnAm 4 года назад +117

    Wow, naming a parameter "string" is quite... courageous:-)

    • @ianpan0102
      @ianpan0102 4 года назад +24

      Unless you're using namespace std, it doesn't really matter.

    • @unsafecast3636
      @unsafecast3636 3 года назад +25

      @Artem Katerynych
      #include
      using namespace std;
      string string(string string) {
      string string = string;
      }
      int main() {
      string string = “string”;
      string(string);
      }

    • @barmetler
      @barmetler 3 года назад +27

      @@ianpan0102 Using namespace std is a cardinal sin anyway

    • @alphazero4587
      @alphazero4587 3 года назад +17

      @@unsafecast3636 Bruh Bruh(Bruh);

    • @НейтральныйМаппер-з2м
      @НейтральныйМаппер-з2м 3 года назад +2

      @@unsafecast3636 god

  • @khoing1111
    @khoing1111 4 года назад +1

    Founding this channel is a god damn blessing for me. Why did I not know about you earlier? Probably spent my whole life of luck on this.

  • @RenatRakhmatullin
    @RenatRakhmatullin 4 года назад +68

    4:40 should be delete [ ]

    • @TernaryM01
      @TernaryM01 4 года назад +8

      He should've tested it on PVS-Studio to see if it can detect the memory leak.

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

      what is the difference ?

    • @Zatmos
      @Zatmos 4 года назад +1

      @@abdallahrashed1947 "delete" destroys a dynamically allocated object and "delete[]" destroys a dynamically allocated array

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

      @@TernaryM01 underrated comment lol

  • @hamdaman3593
    @hamdaman3593 4 года назад +26

    Yes the ps5 part 2 is coming this weekend, whose looking forward to that

  • @chawnneal159
    @chawnneal159 4 года назад +1

    OMG! Ever since your view_string video, I've been obsessed with making my own string_view! After this video I was able to mimic some functionality via referencing the same memory! With some extra steps I can prevent writing! Thanks so much!!

  • @abdullahamrsobh
    @abdullahamrsobh 4 года назад +1

    That video really came, when i needed it thanks Cherno

  • @josephlai7737
    @josephlai7737 3 года назад +2

    @11:31, why is std::move() necessary, even though in the function signature Entity(String&& name), name was specified to be a rvalue? std::move(name) converts a rvalue to a rvalue, and it just looks strange.

  • @cole-nyc
    @cole-nyc 4 года назад +87

    Great video! one comment though: When you heap-allocate an array you have to free it with 'delete[]' instead of 'delete'. Your code frees only the first element of the array.

    • @KishoreG2396
      @KishoreG2396 4 года назад +1

      Technically its UB with char* string literals

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

      what really?

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

      According to the standard, using delete instead of delete[] is UB. In practice, both delete and delete[] are simply forwarded to the libc function "free", and therefore end up behaving the same. Of course I an NOT advocating using delete instead od delete[], that would be terrible practice. But there isn't an implementation out there that only frees the first element. In fact there isn't a function you could use to only free the first element. Even realloc won't do that.

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

      With `delete` instead of `delete[]`, the whole array gets freed, no problem so far, but only one destructor might be called: that of the first element. This doesn't matter in the case of a `char` array, but it can be relevant for more complex objects, which in turn might allocate their own memory (which would then have to be freed again).

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

      @@Flinsch77 that is correct. Thanks for that

  • @upamanyumukharji3157
    @upamanyumukharji3157 5 месяцев назад +1

    hey can someone explain why the copy constructor is called if we do not use explicit type casting/std::move ?
    If the r-value ref entity constructor is called shouldnt name ref be of type String &&?

  • @radioactive5882
    @radioactive5882 3 года назад +2

    Move semantics is basically the same thing as what Patrick said from sponge-bob. Why don't we just move the bikini bottom. In other words, moving a large object without copying it. It would be a real pain to build a town, rebuild it somewhere else, and tear the old one down.
    Thanks btw, your videos semantics and R/L values really helped me out a lot. Would have probably given up on my textbook if I hadn't seen this video.
    The moment I realized how R and L values worked was when you mentioned the phrase "Location Value". All the rules suddenly clicked. I realized L values were like vacant houses for variables. When you assign 10 to x, you are assigning the value of 10 (an R value) to a memory location (l value). Reference variables allow you to sort of bend the rules a bit...

  • @giannitedesco6153
    @giannitedesco6153 4 года назад +5

    You can do printf("%.*s
    ", (int)m_Size, m_Data); rather than that printf loop - it's easier, more efficient, and won't b0rk when you call it from multiple threads since the single call will happen under the stdout lock.

  • @nallaprakash6901
    @nallaprakash6901 4 года назад +8

    Man I was waiting for this from ages 😭😭😭😭, FINALLY Thanks Chernikov 😄

  • @adamhendry945
    @adamhendry945 Год назад +1

    At 5:15, can you confirm, do we need the copy constructor because the default `String` constructor will only copy the `m_Data` pointer, but not its contents (as you mentioned in your Copy Constructor video)? I was a little confused at first because `String m_Name` in `Entity` is not a pointer.

  • @Han-ve8uh
    @Han-ve8uh Год назад

    1. 11:14 When was the old string destroyed? Can someone point the the line of code or trace the lifecycle of which functions are called/objects are created/destroyed?

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

    4:47 shouldn't he have used the delete[] operator instead?
    Also, couldn't I achive the same result using the copy constructor? If I use the same code of the move constructor inside the copy one, I would still be passing the pointer to the block of data and erasing the old pointer so it doesn't delete de buffer. Or am I wrong? But if you need both copy and move construtor to be on the same class, then I understand the need of it.

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

    Great explanation! BTW your hair looks great here

  • @Omnifarious0
    @Omnifarious0 4 года назад +2

    You missed pointing out that if you have a true temporary it will also use the move constructor without needing ::std::move

  • @oraz.
    @oraz. Год назад +1

    I think this topic would be less confusing if it was discussed as "move constructors" from the start instead of move semantics.

  • @TheZenytram
    @TheZenytram 3 года назад +2

    4:27 😲 he used printf( ); i cant believe it.

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

    Need that part 2 reaction video bruh. U be preaching facts and I be feeling that. Keep up the good work my guy. Just run that reaction video for ya boy. You’re killing me Smalls

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

    I KISS YOUR EYES! I didnt unterstand it with my book, but then i found you. R Value Refenrences and Move Semantics are very usefull

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

    Take aways
    1. Move constructor takes rval reference.
    2. Instead of type casting var to rval using (T&&) var, we can use std::move(var)
    const T & takes both rval and lval but if rval is provided to this, it calls copy constructor because intermediate temporary variable is created. To avoid this we use move constructor.

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

      Casting to xvalue

  • @Nick-tv5pu
    @Nick-tv5pu Год назад

    Great video, I always look forward to your stuff.
    That said, at 0:53 isn't that what references (pointers) are for? You don't have to copy a value to/from a function if you just pass/receive a pointer?

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

    if we use the new[] operator for allocating memory for m_Data, shouldn't we use the delete[] operator in the Destructor, or am I missing something ?

  • @shubham91219
    @shubham91219 4 года назад +5

    Hey Cherno, could you please make some videos on lock free programming and memory ordering as well? Thanks for all the great content so far.

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

      Memory ordering is a very tricky subject.

  • @267praveen
    @267praveen 4 года назад +3

    Finally ... It's here. Thanks Cherno.
    Next awaited .....
    Regex
    SFINAE
    Random engines

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

    You should explain the explicit std::move() call in entity ctor. If you look at the ctor of entity it already accepts rvalue so why explicit move if the signatures of entity ctor and string ctor match. Why is function overloading not working here all the way down?

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

    This has finally clicked. It clicked only after I realized that copy constructors, move constructors etc. are just regular constructors which take in a const reference and an rvalue reference, respectively.
    My knowledge of Rust got in the way of understanding this at first.
    So, basically, if you want a constructor to take ownership of the existing data instead of copying it, the constructor should accept rvalue references.
    What's weird is that C++ seems to be different than Rust here.
    Rust's compiler doesn't allow you to use moved objects. As far as I understand in C++ you can go on and use objects even after casting them to rvalue reference and passing them to a constructor. Compiler will let you do it.

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

    It's worth noting that we need to make the moved-from string "hollow" because its original constructor will still fire. In essence, a moved-from object can have multiple instances of its destructor being fired. This, as you can imagine, is rather inefficient. The alternative is what's called a "destructive move," but the design committee of the language couldn't figure out a way to make that fit with the existing object model. For the curious, you can look up Howard Hinnant's and Sean Parent's posts on this matter.

  • @alecmather
    @alecmather 2 года назад +2

    One thing I ran into while going through this video (apologies for my novice) is that you're using this shorthand syntax to assign the Entity->m_Name property in the constructor by doing ": m_Name(name)". Out of curiosity, I tried doing it the way I'm familiar with (just a normal "m_Name = name") inside the body of the Entity constructor, and this caused an error in the destructor of the String class. No idea why/how these two property assignments are different, probably worth an explanation somewhere? Thanks again for making awesome videos!

    • @alexandrumarcel3696
      @alexandrumarcel3696 2 года назад +2

      the difference between ":m_Name(name)" outside of the actual Constructor body and "m_Name = name" is that the first one is calling the Copy Constructor and the second one is calling the Operator = of the String class. Since there is no overloaded version of the operator = the compiler uses the default version provided by the compiler, but as the compiler doesn't know how you want to treat your pointer variable (m_Data) it just simply doing a shallow copy. So "m_Name = name" is basically assigning the pointer name.m_Data to m_Name.m_Data (m_Name.m_Data = name.m_Data), which will result in both name and m_Name pointing to the same address. So when "name" goes out of scope and the Destructor gets called, this will result in "m_Name.m_Data" being a dangling pointer, so when the m_Name object's Destructor gets called it will try to delete the pointer m_Name.m_Data which has been previously deleted when "name" got out of scope. Or at least this is I think happened :D Try to overload the operator = if you want to use the "m_Name = name" version

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

      @@alexandrumarcel3696 you're a G for this explanation lol I also found that he later does a whole video on this difference which also helped a lot, thank you!!

  • @aubertducharmont
    @aubertducharmont 2 месяца назад

    Great video. Hope you one day also cover std::forward, since it is also very important for these semantics.

  • @jh-lp7cg
    @jh-lp7cg 4 года назад +1

    Also, I believe any time the compiler can use Return Value Optimization do not try to use move semantics for return values. RVO will be more efficient.

  • @ישראליעקובוביץ
    @ישראליעקובוביץ 2 года назад

    u give a human touch to a very dry and difficult topic , very helpfull

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

    4:41 why using delete to deallocate an array of characters? is it ok?

  • @vickoza1
    @vickoza1 4 года назад +4

    You made a mistake with the delete operator in the districtor. You need to uses the delete [] and not the delete witch will only delete one character.

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

      It's undefined behavior, so all bets are off, but technically it would only call the destructor for the first item (which is meaningless for a char) and very likely delete all the memory. Which is basically the worst type of undefined behavior, everything works fine today, and tomorrow compiler writers figure out a way to get more speed and your code stops working.

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

    2:35 right arrow key goes click click click click ....

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

    At 1:06 you mentioned passing an object by value to a function, which invokes the copy constructor, thus is wasteful. I understand you are using this use case an example/motivation to explain move semantics. However, isn't the solution simply to pass the object by reference to the function, to avoid copy constructor/waste?

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

    That's why other languages are simply using smart pointers, and C++ also has smart pointers, which are way more convenient and less prone to errors than move semantics

  • @john_codes
    @john_codes 4 года назад +31

    Everyone: RELEASE PT 2 OF THE PS5 REACTION VIDEO
    Cherno: Here's a c++ move semantics video.
    Lol just kidding. I know he's releasing the video on Saturday. Can't wait!

    • @redscorpion9325
      @redscorpion9325 4 года назад +2

      John True Statement,this popped up and I was like where PS5 part 2 video everyone is waiting for😁

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

      How do you know its being released on Saturday?

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

      @M. de k., could be the Discord?

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

      @@redscorpion9325 go to his channel and look at his community post. He said it's coming on Saturday:)

  • @Sala-lh9fu
    @Sala-lh9fu 4 года назад

    Thank you so much fir being so thorough with your explanations! :)

  • @nabil41854
    @nabil41854 4 года назад +2

    Thanks for the great explanation. I just have a note, you are moving the curser a lot making it a bit difficult to follow. cheers

  • @JJFoxLegacy
    @JJFoxLegacy 4 года назад +6

    Dude loved the ps5 video, can't wait for the next part !!!

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

    The destructor should use delete[] because the memory was allocated with new[].

  • @alexbutane5550
    @alexbutane5550 4 года назад +1

    Do all containers in modern C++ have move constructors and move assignment operators by default? and if so how do you use them?

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

    Less typing with "puts" (it adds '
    "), so no need to use printf only to print non-formatted string with "
    " at the end. Anyway great material Cherno.

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

    I followed along and at the 11:50 mark, where you change the String&& cast to using std::move, the result is the copy constructor returns to being used. Any ideas why this could be?

  • @jm10oct
    @jm10oct 4 года назад +1

    what is the meaning of String() = default? what is the " = default" do?

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

    This is freaking greatest explanations ever for move sementic with demo : this explains whats going on underneath actually!! And how move sementic helpful in performance

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

    why we need to explicitly use the std::move() on the Entity(String&& name) :m_Name(std::move(name)) {} ?
    We pass a rValue reference as a parameter, why there is a need to cast an rValue reference passed as parameter to an rValue reference. Isn't that already an rValue reference, why there is a need to cast it again ?

  • @andredesantacruz
    @andredesantacruz Месяц назад

    What's wrong with having a reference parameter to the object you want to "create" and just modify it inside the given function? That way you don't have to return anything and the [out] object passed as an argument will be created or updated in the way you want.

  • @platinoob__2495
    @platinoob__2495 4 года назад +1

    so basically this is for rvalues what reference parameters are for lvalues

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

      Exactly. Its useful to avoid copies (which can be costly for large structures and heap allocations) for the times when what you really want is not a duplicate copy of an object's memory, but to hand off ownership of its memory to another object.

  • @kamilkarwacki9590
    @kamilkarwacki9590 4 года назад +2

    I learned so much about it but still dont know how to use it. So happy to see that you do a video on it as you always go very deep into these topics.

  • @Dante3085
    @Dante3085 4 года назад +1

    5:35 Shouldn't we also delete[] m_data for this String, before we put the other String's data on it ?
    EDIT: I am sorry. At construction time the this String obviously can't have any data that we need to delete before assigning other's data.

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

    Cherno, you could perfectly voice Mike Judge, several B&B characters including Butthead. Did anyone point that out? Quite good resemblance in this video!

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

    really love your videos and i have learn a lot things from them

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

    I still don't understand why when we are creating simple function without parameters as pointers, why C++ compiler generates functions which are copying passed parameters instead of just using parameters from stack with which we are calling this simple function. Is it because C++ vendors just decide that passing by "value" will be feature which will create an extra copy, or there is some extra problem which I don't understand behind the scene.

  • @powerslideita
    @powerslideita 4 года назад +43

    When's part2 of the ps5 event?

    • @J-PSX
      @J-PSX 4 года назад +8

      This week end.

  • @MKolbe-jh6yh
    @MKolbe-jh6yh 4 года назад

    THANK YOU MY FRIEND! YOU JUST SAVED MY SEMESTER :D

  • @iroxenaki2156
    @iroxenaki2156 4 года назад +1

    Why can't we move the char* from the Str(const char* string) to m_Data with the same method?
    Wouldn't something like that work?
    Str(const char* string)
    {
    m_Size = strlen(string);
    m_Data = (char*)string;
    string = nullptr; // although this is a const char* altering it returns no error
    }

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

      It's a pointer. If you copy a pointer you copy not the content which is pointing to but only the address. Next you could use a string view in your case. But this still can easily lead to an dangling pointer, so you should copy it or use a smart pointer.
      To make it short, don't own raw pointer. Use unique or shared pointer for that. It is even better to use container with vales semantics like string or vector.

  • @adityakolachana4621
    @adityakolachana4621 9 месяцев назад

    The way you added cast before bringing in std::move was really the way std::move should always be explained.

  • @abacaabaca8131
    @abacaabaca8131 9 месяцев назад

    What if the data type which needs to be moved into a function via that rvalue reference does not contain any pointer as its field. The data type is only primitive data type.
    For example Vector2 class which consists of x and y coordinate.
    Then how should the move constructor looks like?
    Is it using the operator '=' or using initializer list?
    Example:
    class Vector2{
    public:
    float x=0.0f;
    float y=0.0f;
    Vector2(Vector2&& v):x(v.x),y(v.y){};
    };
    Then, we can use it:
    class GameObject{
    public:
    Vector2 pos;
    Vector2 vel;
    Vector2 acc;
    GameObject(Vector2&& pos, Vector2&& vel, Vector2&& acc):pos(std::move(pos)),vel(std::move(vel)),acc(std::move()acc){};
    };
    To use GameObject:
    GameObject player(std::move(Vector2(10.0f, 10.0f)), std::move(20.0f,20.0f), std::move(5.0f,5.0f));

  • @tarasov9794
    @tarasov9794 4 года назад +13

    C++20 expert: look! innovation!
    Me: *laughs in C99 pointers*

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

    I copied the code step by step and I get this error.
    class "std::basic_string" has no member "Print"

  • @protheu5
    @protheu5 Год назад +1

    Why for (uint32_t... instead of size_t?

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

    i am here after trying to push_back into a std::vector for a class that has two pointers that need to be on the heap when constructed..
    and i tried to use for loop to push_back those elements and C++ does not allow to compile the code because it says the reference might be deleted..
    and the solution is to use move constructor that takes in an rvalue which is a temporary value without an address

  • @musicplaylist3550
    @musicplaylist3550 4 года назад +1

    These videos are here to stay to help people even 5+ years from now 😨

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

    I didn't get why he created a copy constructor at min 5:34. Could any one help?

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

      This is from c++ 11. When you need to provide an implementation when the copy constructor is being called.
      This is a necessity especially when your class contains a pointer as member variables in which it needs to allocates memory on the heap.
      In c++ 17 you do not have to do this. Only use = default; will do. Because the compiler has become smarter.

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

    Can someone please give this guy an award!

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

    So after attempting to learn move semantics/rvalue references for n times ( n >= 100) this finally clicked. Thanks, Cherno!

  • @gvcallen
    @gvcallen 4 года назад +3

    I don't think I've ever been so excited to watch a C++ video before xD. They should put you on Netflix Cherno! ;)

  • @J-PSX
    @J-PSX 4 года назад +25

    The PS5 part 2 is coming this weekend

  • @Destrio_Fury
    @Destrio_Fury 10 месяцев назад

    I don't know if I will get the answer, but here goes nothing. In the previous lValue and rValue video, we have explored that the overload specific to rValue reference gets called taking precedence over "const &" overload if it's present, I have also verified this through a simple test. Then why must we need to explicitly specify it, as @TheCherno has to done in the entity class constructor? Wasn't "string&& name" already an rValue, or it becomes an lValue once passed through a function?

    • @Destrio_Fury
      @Destrio_Fury 10 месяцев назад

      Nevermind, just tested. After an rValue gets passed inside a function, it acts like an lValue(Now that I think about it, it's kind of obvious Lol). That's why the need to explicitly tell that this is an rValue. So can we pass any lValue as an rValue? Yes, and that's the whole point of move operation I guess. It's so trippy, but interesting at the same time.

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

    Anyone know why this has to be done explicitely rather than it being performed behind the scenes by the compiler? I cannot think of a single use case where we might want to copy a r-value.

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

    Why did the destructor got called before the "PrintName" function ?

  • @alexandruoporanu8261
    @alexandruoporanu8261 10 месяцев назад

    When putting your code in an Online cpp compiler the "Destroyed" is printed twice. And that actually makes sense. I do not understand why in the video that happend only once.

    • @justingifford4425
      @justingifford4425 5 месяцев назад +1

      Because he paused the app with cin.get(). The second delete happens after that.

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

    Hi Cherno, you are just amazing.. Well described. But can you help me in finding out where I'm getting wrong, when I say we can do the work, you done in move constructor, in the copy constructor even in that constructor we only getting reference of the object, then what is the need to define separately!

  • @Xameska
    @Xameska 4 года назад +1

    any chance of a map/unordered_map, with hashing/compare function creation for custom key types tutorial?

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

    This helped a lot, thank you!

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

    Hey Cherno. One video on std::decay as well please

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

    Should you use move with functions?
    Let's say:
    std::vector add( std::vector a, std::vector b) { ... }
    and I need to use whatever is passed into a and b later, is it better to pass by reference or move? I know that anything moved shouldn't be used again, so is there a way to move back after the function is done? Like making the parameter a const move or something?
    I ran some trials and move was faster than reference (is that true?) but it's pointless if it leads to undefined behavior.

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

    This is amazing! Thanks!

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

    shouldn't it be
    m_size = strlen(string) + 1; ?
    The next line with new char[m_size] is going to be under-sized, because strlen does not include the null term in reporting the length, therefore need to add 1 more to store it. Non?

  • @crash1013
    @crash1013 4 года назад +3

    Many years ago when I learned K&R C, ignoring the NULL sentinel was one of the most painful programming lessons I learned. Bad things can happen if you don't allocate room for the NULL sentinel and then use C standard library string functions.

  • @supersquare
    @supersquare 4 года назад +1

    Thank you so much Cherno!! You're seriously the best 😊

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

    the destructor of the class String must be like this :
    ~String() {
    delete[]m_Data;
    }
    not like you wrote :
    ~String() {
    delete m_Data;
    }
    because m_Data is an array , right?

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

    If your c-styled string doesn't have null terminating character, then how your strlen() is working, because as I know strlen() also requires null terminating character for its implicit calculation of number of characters in a c-styled string... Can you please clarify!!