 Welcome back. In the previous segment, we discussed a strategy for preventing memory leaks and dangling pointers. In this segment, we are going to see how this strategy can be automated. So we are going to do this by actually implementing the automation process. So towards that, we are going to define a class called capital S string, which will be a class for representing character strings. What we want to do is, we want to be able to store character strings of arbitrary length into objects of this class and we should be able to pass strings to function, we should be able to concatenate them, we should be able to copy them and we should be able to index to get the individual characters of the string and all this we should be able to do without worrying about allocating memory leaks, dangling references and things like that. So what exactly are we wanting and what freedom do we have? So let me sketch that. So let me begin with a sample program. So here is a sample program. So in this, we are assuming that this string class has already been implemented and so we are saying that look we want to create instances of that string class and then we want to assign values to that string class. Then here we want to index into this A. So we want the first element. So if A is PQR, then this is the zeroth character, this is the first character. So they should print Q. Then there is a block over here. So because there is a block, I can define another B inside. So this B should be set equal to A plus A. So it should be set equal to A plus A and what is A plus A? Well, A plus A, we would like it if it means the concatenation of the left operand and the right operand. In this case, A and B, these two A's are the same operands. So it should be a concatenation of this. So at the end of this, this B should be PQR, PQR. Then we should be able to print this B. So there should be a member function print. And then afterwards, after we exit from this block, we should be able to pass our object to a function. So this is an argument to the function and if this is a pass, if this is a call by value, then this value should get copied to the parameter of this function f. So now this is our program. So let us see how C plus plus executes it. So how does C plus plus view the various statements and what is sort of the normal way of executing something like this? So first, this string AB. So the way the string AB works is that C plus plus calls the constructors on A and B. So we should be writing the constructors and therefore we should be able to do whatever we want in when this statement executes. So this is relatively simple. Now the next statement is A equal to B equal to PQR. So how do you interpret this? Well these are operators equal to operators. So this is this operation equal to, if there are several, this is right justified. So first this operation happens. So the way that happens is that this becomes the receiver, there is an operator equal to function and that is called with this. So that is what this is. And then the result of this has to be assigned to this A and so A is called, A is acted upon by operator equal to but with the result of all of these things. So C plus plus will do this. C plus plus is going to allow us the flexibility of defining these functions operator equal to. So the operator equal to functions should make copies, maybe allocate memory, whatever is needed can be done inside those operator equal to functions. And we have to do that and we have to also make sure that while doing that there are no memory leaks and there are no dangling references. So proceeding along in this program we have this A index 1. If you remember we said that A index 1 is also an operator expression, the operator being the square bracket. So this C plus plus reads as A operated upon by the member function operator square brackets with the argument being 1. So again whatever we want to happen as far as evaluation of this A square bracket 1 is concerned we should put in A operator square bracket. Then there is A plus A the new part, there is of course the assignment but that is leave it alone for a minute, this is the new part. And A plus A is again as far as C plus plus is concerned A dot operator A with argument being A. So this A is the receiver, this A is the argument. So if we want this whole thing to produce concatenation then we have to define this operator plus member function suitably. Then B dot print is there but B dot print is fairly standard we just have to have a member function so this should not be too difficult, we just want to print it. But now there is this exit, we are exiting the block. So at this point we want B to be destroyed. So as we said as we have said earlier that all the variables which are created inside a block will be destroyed at the end of the block. For this C plus plus also has a special member function. That special member function is called a destructor and that is written by the symbol tilde. So tilde B is the call that is made and that call is the destructor call. So again if you want something to happen over here then that can be put in the destructor call. And let us take a quick look at this. Would we want something to happen over here? Well here B has been assigned a value. So presumably we allocated some memory. So when we exit that memory should get deleted and that deletion we are going to put that the code for the deletion we are going to put in the destructor of B. So any memory that was associated, any heap memory that was associated with B should be deallocated when the destructor gets called. If we do not do that and if we just destroy the variable B then we will have a memory leak. Finally we come to this call f of a. So f of a is, say let us say it is a call by value in which case this a has to be copied over to the parameter of the function f. So a is passed as argument and a copy of a has to be made and this copying C++ does using something called a copy constructor. Well that parameter is being constructed and it is being assigned a value. The parameter is a variable of the same type as a and so that parameter is being constructed and it is constructed with a copy of a and therefore this kind of, this is called a copy constructor. So we will see this in a minute. So the overall plan is as follows we will define the constructor assignment operator, square bracket operator, plus operator, destructor, print function, copy constructor to do their own work which is say the indexing operator must get the appropriate character. But while doing all of these things or say the plus operator should concatenate the strings but while doing these things if some memory management is needed those corresponding functions should do that memory management as well and thereby we should be preventing memory leaks and dangling references. So that is the plan. Here is one more basic idea that we will need in order to do this implementation. So we will store the string itself, the string that is going to go and sit inside this assigned to this variable that string itself will be stored on the heap while we maintain a pointer PTR to it inside our class. So the idea is that if we store PQR in B what we are going to do is inside the object B we will have a pointer to the heap and PQR itself will get stored on the heap. And whenever we store strings we will terminate them with the null character and this is always done so that we do not have to keep the length of the strings around. The sentinel null will be enough. So our object that we design for a string class is going to contain one member PTR and this is going to be pointing to the heap if there is something in this. If there is nothing in this then this will be set to null. Null is also zero but never mind that we are always going to use null so that we know that we are talking about pointers and this capital null means that the pointer really is invalid. So to avoid dangling references and memory leaks will ensure that each PTR will point to a distinct car array on the heap. Before we store into PTR we will delete the variable at points 2 and when any PTR is about to go out of scope we will delete. So we will delete the memory that points to. So other designs are also possible. One of them is given in appendix G of the book but we will just discuss this simple design. So here is the definition of the class string. So it contains this PTR and it is a pointer to car and then it has these public methods for public member functions. So there is a constructor maybe more than one constructor. So the very basic constructor is going to just set the PTR to be null. So that just says that if I just write string A as I had written earlier string A semicolon then the PTR member of A will be null indicating that A is empty. Then we wanted a print function we wanted to be able to say print a.print so that we can immediately define. So all that we have to do is we have to print the characters that PTR points to. So let us be a little bit fancy and let us check if PTR is not null. In this case we just print everything starting from PTR till the null character otherwise we will print out a message null. So there could be I mean you could have done other things you could have put out a full sentence whatever it is. So this is we have defined one constructor and we have defined one very simple member function but there are lots of other things to be defined. That is what we will do next. So what have we discussed? We said that we wish to design a string class which supports assignment concatenation indexing and all of that and then we took some decisions regarding how to design it. So we said that there will be only one data member in that class which is a pointer. The pointer will point to the heap memory to the position in the heap memory where the actual string will be stored and that string will be stored there null terminated. We will write all the other member functions lots of other member functions that are required say constructors and we will overload the assignment operator, the square bracket operator and all such things to accomplish the required operations and also the required memory allocation and deallocation. So in the next segment we are going to talk about the implementation but before that we will take a short break.