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
@nothingtosee2264 жыл бұрын
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.
@AtlasPrimeV4 жыл бұрын
ok
@platinoob__24954 жыл бұрын
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?
@pratikpatil13834 жыл бұрын
Thanks for starting with Move Semantics.. looking forward for more about this..👍
@shaiavraham29104 жыл бұрын
Can you make a video about the rule of 3 and the rule of 5 and how to implement them properly?
@shah.kairav2 жыл бұрын
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!
@Mzkysti2 жыл бұрын
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 Жыл бұрын
yeah I was wondering! saved me some time!
@alecmather Жыл бұрын
Bless your soul...
@Mmmaris_Chan Жыл бұрын
it helps! should read the comment first before figuring it out myself🤣
@SergeySuper_Silver Жыл бұрын
Thank you very much for your comment! I was confused by the two destructors. But now I know that happens)
@Norhther3 жыл бұрын
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 Жыл бұрын
what's the talk you saw? :)
@torstein5 Жыл бұрын
@@IndyR0ck Probably this one: Back to Basics: Move Semantics (part 1 of 2) - Klaus Iglberger - CppCon 2019
@IndyR0ck Жыл бұрын
@@torstein5 thx!
@mickaelfleurus99444 жыл бұрын
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 !
@ericprincen33453 жыл бұрын
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.
@Brahvim7 ай бұрын
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!
@nabeelsherazi88603 жыл бұрын
Holy shit. I thought I knew things. I don’t know anything. This channel has been such a blessing. Instant sub.
@iiTzLamar4 жыл бұрын
m_Data = new char[m_Size] should be freed with delete [ ] m_Data; and not delete m_Data;
@gideonunger72844 жыл бұрын
It should also be m_Size + 1 when allocating for the null terminator
@Spirrwell4 жыл бұрын
@@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.
@txorimorea38694 жыл бұрын
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[].
@gideonunger72844 жыл бұрын
@@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
@TheJackiMonster4 жыл бұрын
@@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.
@Albert-lr7ky Жыл бұрын
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 Жыл бұрын
Yes, the program needs to clean the continuous block of memory allocated to m_Data.
@DassVeryGood2 жыл бұрын
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!
@aqezzz4 жыл бұрын
Thank you for this video! This is one of my favorite series on KZbin and this is a topic that can be quite confusing but you simplified it beautifully. Great job and keep up the good work
@giannitedesco61533 жыл бұрын
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.
@adityakolachana46215 ай бұрын
The way you added cast before bringing in std::move was really the way std::move should always be explained.
@khoing11114 жыл бұрын
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.
@radioactive58823 жыл бұрын
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...
@shubham912194 жыл бұрын
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.
@KishoreG23964 жыл бұрын
Memory ordering is a very tricky subject.
@jh-lp7cg4 жыл бұрын
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.
@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!
@267praveen4 жыл бұрын
Finally ... It's here. Thanks Cherno. Next awaited ..... Regex SFINAE Random engines
@alecmather Жыл бұрын
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 Жыл бұрын
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 Жыл бұрын
@@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!!
@john_codes4 жыл бұрын
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!
@redscorpion93254 жыл бұрын
John True Statement,this popped up and I was like where PS5 part 2 video everyone is waiting for😁
@redscorpion93254 жыл бұрын
How do you know its being released on Saturday?
@Optamizm4 жыл бұрын
@M. de k., could be the Discord?
@john_codes4 жыл бұрын
@@redscorpion9325 go to his channel and look at his community post. He said it's coming on Saturday:)
@chawnneal1593 жыл бұрын
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!!
@BillThaPill4 жыл бұрын
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
@rafalmichalski48934 жыл бұрын
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.
@ameynaik27432 жыл бұрын
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.
@_Omni2 жыл бұрын
Casting to xvalue
@halaszka29492 жыл бұрын
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
@Omnifarious04 жыл бұрын
You missed pointing out that if you have a true temporary it will also use the move constructor without needing ::std::move
@student99bg Жыл бұрын
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.
@JJFoxLegacy4 жыл бұрын
Dude loved the ps5 video, can't wait for the next part !!!
@TheZenytram3 жыл бұрын
4:27 😲 he used printf( ); i cant believe it.
@maniaharshil9 ай бұрын
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
@xYuki91x4 жыл бұрын
Yesss, I've been waiting for this, THANK YOU :) Will you make a video on Return Value Optimization in the future? I don't really get that topic, my professors aren't good at explaining, but you are
@dmitryincog74554 жыл бұрын
I sorta expected a quarrel in comments along the lines: "you stupid cpp guys invent ridiculous things like exceptions and raii and then try to fix them with move semantics and stuff, you are so dumb", "no, it's you that is dumb, those things are super useful, they help us create really robust software without spending million hours debugging some obscure bugs". I even brought songs popcorn. Oh well, better luck next time
@delulu69694 жыл бұрын
I'm new to coding/programming. I started with JS and PHP. Along the way I learn OOP, and design patterns. Accidentally, I learn to understand Java and C++ syntax thanks to KZbin video suggestions like this. Thank you!😊
@CacheTaFace4 жыл бұрын
Great explanation! BTW your hair looks great here
@abdullahamrsobh4 жыл бұрын
That video really came, when i needed it thanks Cherno
@gvcallen4 жыл бұрын
I don't think I've ever been so excited to watch a C++ video before xD. They should put you on Netflix Cherno! ;)
@kamilkarwacki95904 жыл бұрын
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.
@powerslideita4 жыл бұрын
When's part2 of the ps5 event?
@J-PSX4 жыл бұрын
This week end.
@GreenFlame164 жыл бұрын
Hey, Cherno, the video after Static Analysis in C++ is now marked as private. Was that intentional? Or was it also on move semantics but now you're redoing it and thus removed the old one? Loving your content!
@adamhendry9459 ай бұрын
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.
@vickoza14 жыл бұрын
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.
@oracleoftroy4 жыл бұрын
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.
@beboba2498 Жыл бұрын
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
@RelayComputer Жыл бұрын
I was thinking exactly the same
@J-PSX4 жыл бұрын
The PS5 part 2 is coming this weekend
@midnightcookies86994 жыл бұрын
tomorrow
@redscorpion93254 жыл бұрын
How do you know🤷🏽♂️seems like rumors to me
@alexandrumarcel3696 Жыл бұрын
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 ?
@HamidMehr2 жыл бұрын
So after attempting to learn move semantics/rvalue references for n times ( n >= 100) this finally clicked. Thanks, Cherno!
@Sala-lh9fu3 жыл бұрын
Thank you so much fir being so thorough with your explanations! :)
@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?
@tannishkmankar3998 Жыл бұрын
Still working as of today, ty!
@activex7327 Жыл бұрын
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?
@josephlai77373 жыл бұрын
@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.
@anonymoussloth66872 жыл бұрын
Same question
@charlesyin2892 жыл бұрын
@@anonymoussloth6687 same question
@DIYGuy854 жыл бұрын
Can someone please give this guy an award!
@MKolbe-jh6yh3 жыл бұрын
THANK YOU MY FRIEND! YOU JUST SAVED MY SEMESTER :D
@alexbutane55504 жыл бұрын
Do all containers in modern C++ have move constructors and move assignment operators by default? and if so how do you use them?
@mkhadka123 Жыл бұрын
Ok my head is spinning now
@aylivex Жыл бұрын
The destructor should use delete[] because the memory was allocated with new[].
@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.
@raghavnandwani48902 жыл бұрын
Why did the destructor got called before the "PrintName" function ?
@supersquare4 жыл бұрын
Thank you so much Cherno!! You're seriously the best 😊
@Han-ve8uh11 ай бұрын
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?
@jm10oct3 жыл бұрын
what is the meaning of String() = default? what is the " = default" do?
@alexandrumarcel3696 Жыл бұрын
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 ?
@upamanyumukharji3157Ай бұрын
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 &&?
@marcusantenor793Ай бұрын
Is that C that you are writing? I'm not quite used to C yet. I like the content, but being a noob in c++, writing C throws me off a little bit. but thanks for the explanation.
@fadyhany68182 жыл бұрын
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?
@pandaDotDragon Жыл бұрын
yep
@kartikpodugu Жыл бұрын
we need more real examples of lvalue reference, rvalue references and move semantics
@Destrio_Fury6 ай бұрын
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_Fury6 ай бұрын
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.
@mgancarzjr4 жыл бұрын
Fairly certain this conundrum was a chapter in Effective C++.
@AbstractAbsorption3 жыл бұрын
Why is the memory not corrupted when using the rvalue/temporary's address?
@yousefali995 Жыл бұрын
4:41 why using delete to deallocate an array of characters? is it ok?
@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
@poggly3 жыл бұрын
This helped a lot, thank you!
@tbswerve24973 жыл бұрын
I copied the code step by step and I get this error. class "std::basic_string" has no member "Print"
@RaonCreate3 жыл бұрын
well done explained
@adamodimattia4 жыл бұрын
Please do an episode about explicityly defaulted constructors like String() = default
@Ximaz-8 ай бұрын
I really enjoyed your video, thanks.
@B4dD0GGy4 жыл бұрын
entertaining while *learning*, love it
@AugusteeeJoJo3 жыл бұрын
This is amazing! Thanks!
@mshingote4 жыл бұрын
You still working? or planning to make youtube as fulltime?
@markf59313 жыл бұрын
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?
@LangDau4 жыл бұрын
Good stealth
@SimonBuchanNz4 жыл бұрын
Compare to Rust, where move is the default, and only very basic types are silently copyable, otherwise you need to explicitly clone or borrow (make a reference) to a value
@ckacquah4 жыл бұрын
Your videos always explain everything better 👍... Nice example
@AlmightyFSM4 жыл бұрын
What a colossal PITA
@thestarinthesky_4 жыл бұрын
Thanks for this great video. It would be great if you could slow down a little bit!
@matrixzrymutonium4 жыл бұрын
Are there any resident evil fans here cause re8 or re village showcase is coming on from capcom on re8 reveal.
@ivanpolyakov57464 жыл бұрын
Excellent example with string!
@FrostyChilli Жыл бұрын
What if instead of using String as rvalue to construct Entity, you first created the string variable like String name = "Cherno"? And if you now pass this string into the constructor like Entity entity(name), would it still create a copy? I'd like to think no because the Entity constructor takes in the string as a reference. I understand that if we pass it in as an rvalue like you do in the video then it is required because first, we create the string with "Cherno" and then since it is an rvalue, we need to copy it again in Entity. But with my example above, we wouldn't need to use move semantics, right?
@gharbialaddin61593 жыл бұрын
Entity(const String& name) //:m_Name(name) // here the copy constructor is called { m_Name = name; // here the @ of name and passed to m_Name std::cout
@alexandruoporanu82616 ай бұрын
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Ай бұрын
Because he paused the app with cin.get(). The second delete happens after that.
@MadpolygonDEV Жыл бұрын
im confused about following, when setting other.size =0 arent we also setting our copied data to 0 since we re pointing to the same value? Am I correct to assume that when we use the && function we should think about the variables as pointers instead of references in a sense that were purely assigning pointers now and arent changing the values directly, only the addresses.
@PunisherSamo3 жыл бұрын
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.
@jonsnow85434 жыл бұрын
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?
@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!
@norbertnemesh4 жыл бұрын
You should tell people about swap idiom in this Move Semantics Saga™
@Xameska4 жыл бұрын
any chance of a map/unordered_map, with hashing/compare function creation for custom key types tutorial?
@W0ppi2 жыл бұрын
Ok but you now point to a pointer on the stack. When you leave the scope the pointer the Entity class is pointing to gets invalid. I see in this code the Entity created in the main function would also go out of scope but you could have a function that returns the Entity. The caller could then access an invalid pointer address.
@aegisxiii23844 жыл бұрын
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.
@ZhangYingtiden4 жыл бұрын
Sorry if my question is too obvious... still learning the basics. What happens if in the move constructor, you cannot mutate the m_Data field of your temporary rvalue object? For example, if the String class declares the m_Data field as "const char *const m_Data", then you wouldn't be allowed to assign nullptr to the rvalue object. Should we just avoid doing (sometype *const) in general in C++? Or is there a workaround for this?
@konstantinrebrov6754 жыл бұрын
Finally this topic was explained to me clearly.
@emetchar4 жыл бұрын
I'm >90% sure that Golang should make its way into game dev now that the big players are all x86. Good support for native code, small runtime, and an era where one of the biggest performance challenges is leveraging threads. C++ and tight deadlines are antithetical; write an extensible game engine in a non-sadistic language
@emetchar4 жыл бұрын
I mean, look at the realities of instruction caching and tell me that C++ templates are performant.