At this point, we know an enormous amount about classes in C++. There's one last little bit to add and that is the class destructor is called as the very last call in the class's lifecycle, and then it cleans up the instance of the class. Let's see how it works. Just like all of the other topics of the other class we've talked about recently, there's an automatic default constructor that is provided for you for free, if you have no other destructor defined. The automatic default destructor only calls the destructor of other member variables and that's it. It does nothing else special. So, if you want to do anything like logging or some cleanup of memory, write is your class being destroyed? You're going to want to find a custom destructor. All destructors are never called directly. Instead, constructors are automatically called by the C++ language when your code is compiled, when the object is being reclaimed by the system. So, this happens differently depending on what kind of memory your objects in. If your object is in the stack memory, your destructor is going to be called as soon as the function returns. So, as soon as a function ends, that stack frames gone out of scope, we're going to call a destructor on the objects in that stack frame. If it's on the heap, the destructor is only called when that delete keywords use, to reclaim that memory that the object was using. So, to create our own custom constructor, so we have control over what happens at the end of the class lifecycle. We're going to have to create a member function that follows a specific set of rules, as with the previous class functionality. A custom constructor has to be a member function. The custom constructor has to be the name of the class itself, preceded by a tilde and all the destructors have to have no arguments and no return type. So, there's no ability to change up how we define a custom destructor. There's exactly one way to define it and the only way to define it, is the name of the class itself preceded by a tilde with absolutely no arguments. So, to really see how this constructor works, let's continue our currency example, that we saw in the previous video. Here, I've defined five different functions as part of the class. So, our class is getting loaded with functionality. The default constructor, has zero parameters and says, "Hey, I create $1 and I'm going to donate it to default constructor." Via non-default constructor, the one parameter constructor is going to create a set amount of money based on the volume of it. The copy constructor is going to create a via copy. The destructor is going to destroy the money and the assignment operator is going to transform the money. So, every one of the five different operations that a class might have invoked on, is going to print out slightly different line of code. So, as we worked through a program, we can determine exactly what we expect the program to do and then verify that, with the printed output. So, let's go ahead and look at a piece of code. So, here starting at main. We're down here at the bottom and the mains go and call three functions. It is going to call cube on stack, followed by cube on heap, followed by cube on stack again. We'll go through these and see exactly how we think that the cube is going to exist in memory. So, the first thing, line 23, we call cube on stack, so we jump up to line 12 cube on stack, create a cube of length three. So, we have a cube of length three, so we expect the first line of code to be printed out, to be created three times three times three is $27. Then, it's going to return it, so the second line is we don't actually do anything with the class we created, we're going to return its volume and then because it's on the stack, it's going to get destroyed as soon as we call the return value. So, now we're going to say destroy $27. Third line of code's not going to print out until we go into cube on heap. Cube on heap on line 17, we say C1 creates a new cube of length 10. So, this new cube of length 10 is going to be in heap memory and it's going to be worth $1,000. So, we're going to say create $1,000. The fourth thing that we're going to have printed out, is going to be line 18. Cube C2 creates a new cube. We see there's no arguments here, so it's going create a default cube. So, it is going to create $1 default. Then the fifth thing that's going to happen, is going to be a line 19, we delete C1. So, C1 is the cube that contain $1,000, so we should destroy a $1,000. Now, we return from cube on heap. Because C2 is in heap memory, we don't destroy C2. C2 is still there, we haven't destroyed it, because it's a heap memory, we control the lifecycle of it, it doesn't get destroyed when the function returns. Line 25 calls cube on stack again, so we expect lines one and two, and the two lines associated with cube on stack to repeat. So, the sixth thing is going to be create $27, something is going to be destroyed, $27. So, we expect the output of seven lines, we're going to create destroyed $27. Create a $1,001, destroyed $1,000, create 27, destroyed 27. So, let's go ahead and run the CPP destructor code and see if that matches up with what we expect to happen. Going to CPP destructor directory running make, to compile the code and then running./main, we see seven lines of code outputted. We see it creates 27, destroyed 27. This was our stack memory. We create a 1,000 and create one. This was our memory creating the heap. Then, we deleted the $1,000 one, notice we never destroy the $1, because we've never deleted that memory. Then we create destroyed 27. So, this is exactly what we expected. We created the $1,000 in heap memory and it was destroyed when we called delete. We created the $1 with the default constructor in heap memory, it was never destroyed. So, this is exactly what we expect and this hopefully gives you an idea of exactly how all of this interplays inside of C++. Hopefully, you're getting an understanding of the lifecycle of a class and how these different functions interplay as we make use of the class. The big takeaway with custom destructors, is they're absolutely necessary, when we have to close or free memory or objects associated with the object in question. If we create a new memory inside the class on the heap, we need to destroy it. If we've opened any files or shared any other memory, then we also need to make sure that we define a custom constructor, so we can close a file, remove the shared memory. So, anytime we have these shared resource or system resources, it's going to necessitate a custom constructor. So, those are the uses you seen custom constructors and with a custom destructor, you have a really great idea of the entire lifecycle of the class, from the constructor, to copy and assignment operators, to find the end of life with the destructor. What's really interesting now, is how do we actually use all of this powerful C++ semantics to build awesome things in C plus plus? We'll get started with doing more amazing things with classes next video. I'll see you then.