SMART POINTERS in C++ (std::unique_ptr, std::shared_ptr, std::weak_ptr)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up guys my name is a channel welcome back to my state boss last series today we're gonna be talking all about smart pointers in C++ so as my pointers are a topic that has come up a lot recently in my videos and people requesting this and what is a smart pointer should I be using smart pointers and all that today we just goes over what they are we're not really going to get into depth about what why I think you should or shouldn't be using them and all that stuff and my opinions about smart pointers in general I'm gonna save that for another video today we're just gonna focus on what a smart pointer is and what it can do for you so earlier we talked about what new and delete does new allocates memory on the heap and delete is needed to delete that memory to free that memory because it won't be freed automatically smart pointers are a way to automate that process that's all they are right smart pointers mean that when you call new you don't have to call delete and in fact in many cases with smart pointers we don't even have to call new so a lot of people tend to have this kind of programming style and safe as possible they never ever call new or delete and smart pointers are best their way to make that happen so smart pointers are essentially a wrapper around a real raw pointer when you create a smart pointer and you make it it will call new and allocate your memory for you and then based on which my pointer you use that memory will at some point be automatically free so let's take a look at the first kind of an simplest smart border that we have unique pointers so a unique pointer is a script pointer meaning that when that pointer goes out of scope it will it will get destroyed and it will call delete we actually talked about how object lifetimes work and how you can leverage the power of stack allocation all that in the last video so definitely check that out if you haven't already but that is basically our script points work or unique pointers there isn't they're called unique pointers it because they have to be unique you can't copy a unique pointer because if you copy a unique pointer the memory that it's pointing to they'll basically you'll have two pointers two unique pointers pointing to the same block of memory and when one of them dies it will free that memory meaning that suddenly that second unique pointer you had pointed to the same book of memory is pointing to memory that's been freed so you cannot copy unique pointers you need pointers are for when you want a skrub pointer and that is the only reference to that pointer you actually want let's take a look at an example a unique pointer so the first thing you'll need to do to get access to all these smart pointers is include memory now we have this entity class here or what is is the constructor on a destructor with print when we create the entity R when we destroy the entity just so that we can kind of look into the behavior of these smart pointers so over here in main if I want to create a unique pointer which lasts in a certain scope so I've made a new scope you an empty scope inside here I'm going to allocate my entity using a unique pointer the way I'll do that is I'll type in SV unique pointer I'll give it a template argument of entity and then I'll give it a name such as entity and then I've kind of got two options I could either call the constructor here and type in new entity like this note that you actually won't be able to do this kind of construction because if you look at unique pointer the constructor is actually explicit meaning that you do have to call the constructor explicitly there's no implicit kind of conversion or converting constructor so that's one way to make unique point and then you can kind of access it like you would anything else if I wanted to call a function here we don't even have any functions but if I were to call a function here I would just access it through the arrow operator and everything would be exactly the same as if this was just a roll pointer the preferred way though to construct this would actually be to assign it to STD make unique with that entity there the primary reason that that's important for unique pointers is actually due to exception safety we'll talk about exceptions at some point in this series I don't like exceptions at all so that's gonna be an interesting episode whenever that happens but anyway the preferred way to make this is to call make unique because it is slightly safer if if the constructor happens to throw an exception you weren't end up having a dangling pointer with no reference and that's a memory leak anyway the idea is that once we make this unique pointer we can call whatever method we want and you'll see that if I hit f5 to run my program our entity gets created here and then if I hit f10 to get out of this scope our entity is destroyed now okay so automatically when this code ends our entity gets destroyed that's the simplest my pointer that we have it's very useful it's got a very low overhead it doesn't really even have an overhead it's just a stack allocated object and when when that stack allocated object eyes it will call delete on your pointer and free that memory the problem with this is as I meant if you want to copy that at that point if you want to kind of share that point and maybe pass it into a function or have another class story you're gonna run into a problem because you can't copy it and if you take a look at this if I was to try and make another unique pointer here called easy row or something like that and assign it to entity I actually can't do that and you'll get kind of an error message here which looks a bit weird if you go to this unique point of definition and you actually scroll down a bit you'll see that the copy constructor and the copy assignment operator are actually deleted which is why you get a compile error if you try and do something like this and that's that's there specifically to prevent you from digging yourself into a grave because you cannot copy this because because again as soon as one of these unique pointers dies they all essentially kind of die because the memory the underlying memory of that peepal gated object gets freed so if you like sharing that's where shared pointer comes in and share pointer kind of works a bit a bit differently it's a bit more hardcore if you will because it does a lot of other stuff under the hood the way that a shared pointer is implemented is actually kind of up to the compiler and the standard library that you're using with your compiler however in pretty much all systems that I've seen it's it's using something called reference counting we're gonna have a specific video about reference counting and in fact a lot of these things in the standard library we're actually gonna have videos where we implement them ourselves because they're great examples of how C++ works and how we can kind of use C++ so we're going to definitely write our own unique bonus montoya shared point all of that kind of stuff in the future as well as other kind of satellite bury features so if you if you want that that's coming but the way the shared pointer works is via reference counting and reference counting is basically a practice where you keep track of how many references you have to your pointer and as soon as that reference count reaches zero that's when it gets deleted so as an example I create one shared pointer I then create another shed pointer and copy that my ref count is now two so one for the first one once the second one that's two when the first one dies my reference count goes down one so I'm on one now and then when the last one dies my reference count goes back to zero and I'm dead so the memory gets freed so to use a shared pointer you just type in STD shared point I'll I'm just get rid of this compile error will do NC over here as the template parameter I'll do shared entity as the and I'll set this equal to STV make shared MT now in this case you could have also done a new entity like this and you can see if that compiles fine except you definitely don't want to do that with shared pointer with unique points are really the only reason not to call new directly is because of exception safety built with shared pointer there's actually going to be a difference because shared pointer has to allocate another block of memory called the control block where it stores that reference count and if you create if you first created a new entity and then pass it into the shared pointer constructor it has to allocate that's test2 allocation that's right because you constructing the entity first and then be shared pointer has the controller cut it has to construct its control block whereas if you do make share it can actually construct them together which is a lot more efficient and also for those of you people who hate new and delete this obviously gets rid of the new keyword from your codebase because you're just calling a city make shared instead of new entity so I bet you guys love that so with shared pointer you can of course copy it and yeah I mean if I type in code like this it's gonna work perfectly fine I could also move this outside to here and just have this over here let's let's make another scope for fun so I can kind of demonstrate how this works and you drag this over here alright so I've got kind of two scopes again the first one I've got is 0 that's it and then in this one I have my shed entity I'm going to assign easier with my shed entity I'm just going to comment out all get rid of all that other code with the unique pointer so now what will happen is if I hit f5 the first thing that's gonna happen is I'm going to construct my entity so that's done good it's created I'm going to assign this when the first coat dies this challenge she dies however you can see that it hasn't destroyed my HT it hasn't deleted it because a 0 is still alive at holding a reference to that entity now when I have 10 that's when it dies when all the references are gone when all of the stack allocated kind of objects that keep track of all the shared pointers when they die when they get read from memory all of them that's when your underlying entity gets deleted all right and finally there's something else that you can use with shared points are called a weight pointer and what you can do with that is just declare it like it was anything and kind of give it the value of a share density and what this does what this does is kind of the same as if you were to copy that share entity and increase the ref count except it doesn't including it doesn't increase the ref count when you assign a shared pointer to another shared pointer thus copying it it will increase the ref count but when you assign a shared pointer to a weak pointer your orange increase the ref count so this is great for if you kind of don't want to take ownership of the entity like you might be storing a list of entities and you don't really care if they're valid or not but you just want to store like a reference to them right with weak pointer you can kind of ask it hey is this is this still even alive and if it is you can do whatever you need to do but it won't keep it alive because it doesn't actually increase the ref count meaning that if I worst was to actually replace this shed and see where the weak pointer and then basically did the exact same thing that I did before then the entity will get credit here it'll get assigned to the shed and see but when I exit the first car that is what it gets destroyed so this weight pointer is now pointing to an invalid and T however you can ask a weak pointer are you expired are you still valid so that's pretty much smart pointers now as for when you should use them you should probably try and use them all the time if I'm being completely honest they automate your memory management they they they get rid of all they did they prevent you from accidentally leaking memory by forgetting to call delete they're really quite useful shared pointer specifically has a bit of an overhead because of its reference counting systems but then again a lot of people a lot of people who tend to write their own memory management systems tend to have a bit of an overhead as well so it's kind of it's a very delicate topic because you have this new breed of C++ programmers now who only use these kind of features and then you have like the optical people who using you and delete I'm kind of a bit of both because there is a time where you want to use unique pointer or shared point two perhaps but there's also a time where you need new and delete so don't think that this has completely replaced you in delete in my opinion it has absolutely not replaced new and delete it's just something that you should probably do when you just need to declare a heap-allocated object and you don't particularly want to tidy up after yourself because you don't need to kind of explicitly call to later explicitly manage that memory in those cases you should be using a smart pointers usually use unique pointer whenever you can because it has a lower overhead but if you absolutely need to share between objects so you just can't use any just can't use a unique pointer then use a shared pointer but definitely going that order first you think pointer first preference share point a second preference hope you guys enjoy this video if you did even if that like button on our YouTube check I said it was like the said it was there last time but now it's like in the middle it's like here or something out in our anyway you can click that like button if you enjoyed this video leave any suggestions you have for future videos and all that in the comment section below as well as any questions you may have I have a discord server where you can also ask questions link in the description below and if you really like this video and you like this series and you want to support it you want to see more videos then you can go to patreon.com/scishow turner pick up some sweet rewards by helping to support this series I will see you guys next time goodbye [Music]
Info
Channel: The Cherno
Views: 281,171
Rating: 4.9650126 out of 5
Keywords: thecherno, thechernoproject, cherno, c++, programming, gamedev, game development, learn c++, c++ tutorial, pointers, smart pointers, std::unique_ptr, std::shared_ptr, std::weak_ptr, std::auto_ptr, memory, new, delete
Id: UOB7-B2MfwA
Channel Id: undefined
Length: 11min 37sec (697 seconds)
Published: Mon Sep 11 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.