C++ Tutorial: Rule of 5 [move constructor, move assignment operator]

  Рет қаралды 17,375

Professor Hank Stalica

Professor Hank Stalica

Күн бұрын

We continue our series on C++11 features you might have forgotten or never learned. Specifically, we will talk about the move constructor and move assignment operator and how it can help you write more efficient classes. In the example, we'll improve efficiency from O(n) to O(1) for the selected operations.
As part of the discussion, we'll write a class that includes these methods and other overloaded operators.
Since we're including the move methods, we'll be including a destructor, copy assignment operator, and copy constructor.
Once done, we've implemented a class that follows the Rule of 5.
A great tutorial for not so beginners.
// Writing the Move Code //
~ 22:00
// Source Code //
www.dropbox.co...
// Learn More //
Check out my complete C++ videos playlist:
• Playlist
Value categories:
en.cppreferenc...
Rule of three/five/zero:
en.cppreferenc...
// Consider supporting this channel in multiple ways //
ko-fi.com/prof...
paypal.me/hank...
Bitcoin: 177wfkQwzXiC8o2whQMVpSyuWUs95krKYB
Dogecoin: DRK2HDp3ZkkbFpvGZnVgMVosnBhPv8r3uP

Пікірлер: 75
@ProfessorHankStalica
@ProfessorHankStalica 2 жыл бұрын
Thanks to commenter Tal Jerome for pointing out a small mistake I made, but a big one. The move assignment operator does have a memory leak in it. Here is a quick fix: Foo& operator=(Foo&& rhs) noexcept { cout
@xtech3408
@xtech3408 Жыл бұрын
can we continue to mark operator=(&&) as noexcept, if delete[] appeared in it?
@alexandruteodor3585
@alexandruteodor3585 Жыл бұрын
Why is it necessary to write // if (this != &rhs) //? How can a named object assign an r-value with the same address?
@anushaaladakatti4145
@anushaaladakatti4145 Жыл бұрын
Thank you for the explanation. Don't we need this fix in move copy constructor as well?
@francoiswessels8062
@francoiswessels8062 9 ай бұрын
​@@alexandruteodor3585​Good question, makes me wonder as well ?!?!
@walidhanniche5545
@walidhanniche5545 3 ай бұрын
You can swap the arrays for move assignments and let the destructor free the original array
@pdd3
@pdd3 2 жыл бұрын
Professor, you're a gem! Keep up the good work.
@ProfessorHankStalica
@ProfessorHankStalica 2 жыл бұрын
Thanks for the feedback! Glad the video helped! (Cough, Super Thanks, Cough :-D)
@timothymusson5040
@timothymusson5040 8 ай бұрын
Perfect pace. Yes, it seems like a long video for the topic, but it takes longer than you’d think to cover it front to back like you did. Great job, and thanks for putting this together!
@ProfessorHankStalica
@ProfessorHankStalica 8 ай бұрын
Glad it was helpful!
@francoiswessels8062
@francoiswessels8062 9 ай бұрын
One of the very best videos out there on this topic
@andrewjewett1056
@andrewjewett1056 2 жыл бұрын
I found this video very helpful. Thank you for making it.
@ProfessorHankStalica
@ProfessorHankStalica 2 жыл бұрын
Glad it was helpful!
@Wolverine_261
@Wolverine_261 28 күн бұрын
Thank you so much The concept was difficult, but you explained it so well and perfectly made it f extra difficult lol
@ProfessorHankStalica
@ProfessorHankStalica 27 күн бұрын
Glad it helped!
@akhilkhubchandani2632
@akhilkhubchandani2632 2 жыл бұрын
Really helpful ! Keep making such quality videos :)
@ProfessorHankStalica
@ProfessorHankStalica 2 жыл бұрын
Thanks tons, appreciate the comment. :-D Glad you got some value out of them!
@TalJerome
@TalJerome 2 жыл бұрын
Your move assignment operator has a memory leak because you didn't free the old array before overwriting it with the other one
@ProfessorHankStalica
@ProfessorHankStalica 2 жыл бұрын
Yup, you are absolutely correct, sir. Thank you for finding my mistake. I will pin a correction.
@alexandruteodor3585
@alexandruteodor3585 Жыл бұрын
Thank you! ♥♥♥ These notions are finally clear to me.
@shwethab2520
@shwethab2520 4 ай бұрын
Best explanation I ever found ❤
@ProfessorHankStalica
@ProfessorHankStalica 4 ай бұрын
Wow, thanks!
@xtech3408
@xtech3408 Жыл бұрын
omg, i must assign null to that ptr in temp object🤦‍♂🤦‍♂🤦‍♂🤦‍♂🤦‍♂🤦‍♂🤦‍♂🤦‍♂. It prevents freeing memory in destructor for temp object by pointer copied to new object. This mistake costs me hours of headache. Thanks, your guide was very structured and detailed😄😄😄😄😄😄
@ShivarajappaP-o2g
@ShivarajappaP-o2g 28 минут бұрын
thank you so much for the video
@RakeshKumar-fu2hp
@RakeshKumar-fu2hp Жыл бұрын
hello Professor, I tested this code in C++14. Adding two objects "h = f + g;" doesn't invoke copy constructor when move assignment & move constructor are not defined. It only calls +operator and default constructor (temporary object within +operator function) and finally assignment operator. Is there a change in behavior in C++ 14 ?
@ProfessorHankStalica
@ProfessorHankStalica Жыл бұрын
I'd have to see the code to be certain, but sounds like it's behaving exactly as it should be. No new object was created requiring a copy constructor with h = f + g. Copy constructor gets invoked in one of these two situations: Foo g; Foo f = g; or Foo g; Foo f(g);
@monicadasi2504
@monicadasi2504 Жыл бұрын
@@ProfessorHankStalica Prof.Stalica In C++14 , this is how the order is getting executed. I don't see move / copy constructor getting called instead for h = f+g (I see operator+ followed by copy/move assignment operator execution) . 0 3 6 9 12 copy c'tor called 0 3 6 9 12 operator+ executes move assignment operator executes 0 3 6 9 12 0 3 6 9 12
@floatoss
@floatoss Жыл бұрын
@@ProfessorHankStalica actually Professor, I think it should not get called, as another commentor has pointed it above 4 months ago. When we do "h = f + g", the "f + g" invokes the "overloaded+" operator, and then the assignment calls the "overloaded=" operator right? But in your program, it seems to call the copy constructor. I'm not sure why it is the case, I haven't tested on mine yet. Timestamp is 18:18.
@francoiswessels8062
@francoiswessels8062 9 ай бұрын
same
@francoiswessels8062
@francoiswessels8062 9 ай бұрын
I tested it with his code and my own using C++14, and it does the same thing. It must be some C++14 feature. I can't think of what else could cause this?!?!
@user-ge2vc3rl1n
@user-ge2vc3rl1n 10 ай бұрын
Absolutely fantastic and brief
@chudchadanstud
@chudchadanstud 8 ай бұрын
That background is trippy
@nom9d825
@nom9d825 Жыл бұрын
thanks for video! very good explanation. finally getting sense about rvalue reference.
@djamelbgd301
@djamelbgd301 10 ай бұрын
Professor, your explanation was very clear. I really understood the Lvalue and Rvalue. Just at 18:15, why were both the copy constructor and copy assignment executed? Is a temporary object created by the copy constructor to hold 'f+g' and then assigned to 'h' with copy assignment?
@ProfessorHankStalica
@ProfessorHankStalica 9 ай бұрын
Yes. f+g results in a new object being created.
@timothymusson5040
@timothymusson5040 8 ай бұрын
@@ProfessorHankStalicaand that object is the R-value described at 8:47?
@bharatsarda
@bharatsarda 2 жыл бұрын
Fantastic video
@ProfessorHankStalica
@ProfessorHankStalica 2 жыл бұрын
Thanks for the comment and glad you liked it!
@faizaniftikhar
@faizaniftikhar 5 ай бұрын
loved it. 30 mins passed in a breeze. Though I don't think you explain why you used && instead of & in move constructor and move assignment operator overload
@ProfessorHankStalica
@ProfessorHankStalica 5 ай бұрын
That's the syntax we use to designate it as the move constructor or move assignment operator.
@dryoldcrabman6890
@dryoldcrabman6890 Жыл бұрын
BRUH you have a memory leak in your code :( tricky tricky tricky. Valgrind doesn't lie. I didn't even notice it. Foo& Foo::operator=(Foo&& rhs) noexcept { std::cout arry if (this->arry) delete[] this->arry; this->size = rhs.size; this->arry = rhs.arry; rhs.arry = nullptr; rhs.size = 0; } return *this; } But good example! Thank you for the video.
@ProfessorHankStalica
@ProfessorHankStalica Жыл бұрын
Yup, see the pinned comment. A generous commenter pointed it out a while ago and I pinned the comment for all future viewers. Thanks for posting the reminder though.
@nanoometaleiro
@nanoometaleiro 9 ай бұрын
Excellent content. Thank you.
@ProfessorHankStalica
@ProfessorHankStalica 9 ай бұрын
You're very welcome!
@GEAG08
@GEAG08 Жыл бұрын
omg, your way of teaching is so easy to understand, thanks a lot for these videos Professor Hank!, btw just wanted to ask about the memory leak fix. Is the reason to set rhs.size = 0;, is to just set to null the remaining instance of the temporary object right?
@ProfessorHankStalica
@ProfessorHankStalica Жыл бұрын
Setting size = 0 would be to set the variable so it reflects the size of the container the class is managing. So, if size represents the size of an array, and there are no elements in the array, or it's a partially-filled array with no values currently being stored, then size should be 0.
@nesessoftware
@nesessoftware 9 ай бұрын
thank you very much
@ProfessorHankStalica
@ProfessorHankStalica 9 ай бұрын
You are welcome very much!
@francoiswessels8062
@francoiswessels8062 9 ай бұрын
If my understanding is correct, the Move constructor does not require that the resources need to be freed, since the object into which the resources are copied from the rvalue does not yet exist, and thus there is nothing to free. However, this is not the case with the move assignment operator, for which resources are being copied to an already existing lvalue, for which resources needs to be freed, before updating its pointer to the rvalue resource...?
@ProfessorHankStalica
@ProfessorHankStalica 9 ай бұрын
Depends on what you are trying to do. The big idea is why create a new resource and copy from one object to another, if the existing object is going to be destroyed anyway. Just transfer it's ownership. If I'm going to die, why don't I just leave you my stuff instead of making a copy of all the stuff I have to give to you?
@user-cv6ze5cr1h
@user-cv6ze5cr1h 2 жыл бұрын
great video! I would like to ask a question- why move assignment doesn't delete the array h is holding before swapping between h and f+g arrays? isn't it going to cause leaking problem? thank you!
@ProfessorHankStalica
@ProfessorHankStalica 2 жыл бұрын
Cause then you wouldn't have the array anymore... The idea of doing a move operation is to transfer ownership of a resource from one object to another, not destroy it. It's not a leak because another object has taken control of it. Maybe I misunderstood the question?
@user-cv6ze5cr1h
@user-cv6ze5cr1h 2 жыл бұрын
I understand! Thank you !!
@SuperSlugger94
@SuperSlugger94 2 жыл бұрын
I do believe the move assignment operator, in this case, is creating a memory leak! If you are moving f+g into h you still need to delete the array that h was holding prior to the move! Example: h = {1,2,3} f+g = {4,5,6} Moving f+g into h: h = {4,5,6} But {1,2,3} (which h previously allocated) has not been deallocated and is now causing a memory leak
@IndrajeetDevre
@IndrajeetDevre 6 ай бұрын
Thanks for the video. I have one doubt. if we can have move constructor and move assignment operator, can't we just avoid copy constructor and assignment operator ?
@ProfessorHankStalica
@ProfessorHankStalica 6 ай бұрын
Possibly. Depends on what you are using the class for. Although, the rule of 5 says if you have one, you should all the others.
@3DMage
@3DMage Жыл бұрын
How does the Rule of Five apply within the context of inheritance and polymorphism? For example, if I create a base class that follows the Rule of Five, would the derived classes that inherit from the base class also need to follow the Rule of Five?
@ProfessorHankStalica
@ProfessorHankStalica Жыл бұрын
Yes, it still holds. A class is a class and a derived class is a base class. You always have to ensure you are managing your resources correctly. However, remember, you are inheriting stuff with inheritance, so the amount off additional work is going to depend on what you do in the derived classes.
@mayankarora7705
@mayankarora7705 Жыл бұрын
Hey, Is it okay to declare the operator
@ProfessorHankStalica
@ProfessorHankStalica Жыл бұрын
I think you can define it inline, but don't remember 100%. Try it!
@francoiswessels8062
@francoiswessels8062 9 ай бұрын
I believe that's what he did when he marked it as friend function inside the Foo class
@mayankarora7705
@mayankarora7705 Жыл бұрын
how is copy constructor being called when h = g + f; Isn't it suppose to call assignement operator?
@ProfessorHankStalica
@ProfessorHankStalica Жыл бұрын
It gets called as a result of the g + f. Imagine if g and f were int variables that held, say, 2 and 5. A 7 gets temporarily created before it gets assigned to h. You could say the "copy costructor" for 7 has to get called when the 7 is "constructed". After that, the 7 gets assigned to h. So it is here with objects.
@mayankarora7705
@mayankarora7705 Жыл бұрын
@ProfessorHankStalica yes, but the object h has already been created. So ideally it should have called the overloaded assignment operator. Please crct me if my understanding of assignment operator is wrong. In my understanding, copy ctor is called whenever we are creating a new object from some existing one. Like foo obj(obj1) and foo obj = obj1: but assignment operator is called when foo obj; obj = obj1;
@ProfessorHankStalica
@ProfessorHankStalica Жыл бұрын
It calls both, as explained above. A new temporary object is constructed as result of the addition (calls the constructor) and then is assigned to h (calls operator=).
@mayankarora7705
@mayankarora7705 Жыл бұрын
@@ProfessorHankStalica thanks man. 🔥
@floatoss
@floatoss Жыл бұрын
​@@ProfessorHankStalica actually Professor, I think it should not get called, as another commentor has pointed it above 4 months ago. When we do "h = f + g", the "f + g" invokes the "overloaded+" operator, and then the assignment calls the "overloaded=" operator right? But in your program, it seems to call the copy constructor. I'm not sure why it is the case, I haven't tested on mine yet. Timestamp is 18:18.
@LatitudeMexico
@LatitudeMexico Жыл бұрын
Why aren’t you using std::move ? Thx
@ProfessorHankStalica
@ProfessorHankStalica Жыл бұрын
Mostly because that's not covered in my course in which this video is used.
@mba2ceo
@mba2ceo 2 ай бұрын
please no reason to make videos 60 frame rate - 1080p30 is purfact
@ProfessorHankStalica
@ProfessorHankStalica 2 ай бұрын
You are correct. In my later videos, I try to keep it to 720p30 or 1080p30. In my earlier videos I wasn't so good about it. Thanks for the comment.
@mba2ceo
@mba2ceo 2 ай бұрын
@@ProfessorHankStalica U still the BEST teacher I ever had - any subject :) best wishes
@jia7307
@jia7307 2 жыл бұрын
Hi Professor, thanks for the video. It was really helpful! I tried copy/pasting the code in my local coding environment, and found that the output is different on my machine. the program seems to be calling the default constructor instead of the move constructor. Output at 26.44: 0 3 6 9 12 Copy constructor executes. 0 3 6 9 12 0 0 0 move constructor executes. move assignment operator executes. 0 3 6 9 12 0 3 6 9 12 Output on my machine: 0 3 6 9 12 Copy constructor executes. 0 3 6 9 12 0 0 0 *default constructor executes* move assignment operator executes. 0 3 6 9 12 0 3 6 9 12 Any idea as to why this is the case? Please let me know, thanks!
@ProfessorHankStalica
@ProfessorHankStalica 2 жыл бұрын
Hi Jia, check out the fix to the memory leak problem I had that was pointed out by Tal and also trace through your code and double check that all the code is there.
C++ Tutorial:  The Rule of Three
22:06
Professor Hank Stalica
Рет қаралды 5 М.
Cute
00:16
Oyuncak Avı
Рет қаралды 4,7 МЛН
Пришёл к другу на ночёвку 😂
01:00
Cadrol&Fatich
Рет қаралды 5 МЛН
У ГОРДЕЯ ПОЖАР в ОФИСЕ!
01:01
Дима Гордей
Рет қаралды 7 МЛН
Will A Guitar Boat Hold My Weight?
00:20
MrBeast
Рет қаралды 143 МЛН
std::move and the Move Assignment Operator in C++
16:06
The Cherno
Рет қаралды 171 М.
Why i think C++ is better than rust
32:48
ThePrimeTime
Рет қаралды 302 М.
C++ Tutorial: Lambda Functions
23:11
Professor Hank Stalica
Рет қаралды 2,4 М.
Move Semantics in C++
13:10
The Cherno
Рет қаралды 291 М.
31 nooby C++ habits you need to ditch
16:18
mCoding
Рет қаралды 778 М.
how Google writes gorgeous C++
7:40
Low Level Learning
Рет қаралды 874 М.
Cute
00:16
Oyuncak Avı
Рет қаралды 4,7 МЛН