 So, let us get going. So, this is about constructor and destructor functions which we already studied in the last lecture. The main point to remember here is that whenever an object of a particular class is allocated when memory for that is allocated immediately after that the constructor function is invoked on that object and similarly a destructor function is invoked on an object immediately before it is deallocated. So, both the constructor and the destructor actually have access to the data members of the object because the constructor is called immediately after the object is allocated. So, it can access the data members and a destructor is called immediately before the object is deallocated. So, that also has access to the data members. So, we saw this example last time that the constructor function basically looks like a function defined within the class has the same name as the class does not have a return type and can take list of parameters or may not take any parameter and all we require is that if there are multiple constructor functions their list of typed parameters should be different ok. And we saw this example last time. So, even if I have multiple constructor functions there is no confusion in which one is being called. For example, here I am passing three double valued parameters. So, this constructor is called and here I am not passing any parameters. So, this constructor is called and otherwise they are just like normal member functions. Similarly, a destructor as I said is invoked just before the object is deallocated and the convention is that we put a tilde before the name of the class and that becomes a destructor function once again defined within the class and it does not take any parameters does not have any return type. And you cannot have multiple destructors of the same class because all of them would have the same name and all of them would not take any argument. So, it would be difficult to figure out which destructor you wanted to call if there were multiple destructors. So, you cannot have multiple destructors of the same class ok. So, we saw this example last time essentially every time an object is allocated the constructor is called it is allocated here again. So, the constructor is called this object is not available outside this pair of braces because it is declared within this pair of braces. So, over here that object is deallocated. So, the destructor is called another allocation, deallocation and finally, at the end of main when main returns all the local variables of main are freed up. So, the object A is again deallocated. So, the object A which is the local variable of main would be deallocated here when main returns. And so another destructor would be called right. So, one destructor is called here for this object B another destructor is called here for this dynamically allocated object pointed to by P. The third time a destructor is called is here when the object A is being freed up right. And within the destructor function like it is just like any other member function. So, I could access other member functions I could have other statements whatever. So, we have already seen this in the last class what I want to do now is go slightly beyond this and try to understand a little bit more about the usage of constructors and destructors. So, this is the two constructor functions for the V 3 class this is the destructor function for the V 3 class. Now, you know if you think about it this is the main program and this is the class V 3. So, here I am invoking the scale object the scale member function on the receiver object A right when I say A dot scale A is an object of class V 3 and when I say when I say A dot scale with parameter 4.0 I am invoking the member function named scale on the receiver object A. So, since we can call member functions on the receiver objects by just putting a dot the question is can we do the same thing with constructors and destructors. And the answer is I mean in order to call a constructor you need an object on which to call right and the moment you create that object the constructor will be called on this. So, you cannot have an object and then say I want to call the constructor on that object explicitly. However, what you can do is you can do something like this you can say V 3 2.0 2.0 2.0. So, this is almost like a function call, the name of the function that I have used here is the name of the class V 3, but of course within that class V 3 there is a constructor by the name V 3 right. So, you know unlike A dot sum which is a member function being called on a receiver object I cannot write A dot V 3 right A is a object of class V 3 and V 3 is a member function within that but it is the constructor function. So, I cannot call A dot V 3 on it. However, I can say V 3 2.0 2.0 2.0 effectively what this is doing is this is going to create an object of class V 3 and immediately call the constructor on it. So, this almost looks like a function call, but this is an explicit constructor invocation the difference from a member function invocation is that this member function is called on a receiver object. If I have to call this constructor on a receiver object I have to first declare that receiver object, but the moment I declare that receiver object the constructor already gets called on it right. So, this is the way that you can explicitly invoke a constructor function not on a receiver object, but directly and what it will do is it will create an object of the appropriate class and on that object it will call this constructor. So, for example, here I am creating an object of class V 3 to and the constructor of that is being passed the parameters 2 2 2 and that object of class V 3 with whatever you know initialization the constructor has done is then passed as a parameter to some. You can also specify default values of parameters in a constructor. So, for example, here is the constructor for V 3 here are w v x, w v y, w v z are the 3 parameters double value parameters and within the parameter declaration I could also say equals 0.0 equals 1.0 equals 2.0. So, these specify the default values of these parameters and in fact this is nothing special about constructor functions in any function in C plus plus you can specify default values of parameters which means when you call that function if you provide a value for the parameter well and good if you do not provide a value for the parameter it will take the default values right and then I could do this initialization here. So, this is an interesting example. So, if I have this constructor then if I just declare an object a of class V 3 without providing any you know parameters to the constructor that is fine because it can invoke this constructor and use all the default values. So, basically you will get if this is equivalent to passing the default values 0.0 1.0 2.0 ok. If I specified just one of the parameters then also it is fine because the other two parameters can get their default values. So, this is equivalent to saying 1.2 1.0 2.0 this is equivalent to saying 1.2 1.3 2.0. So, of course, the if you are specifying one parameter that will be used as a value for the first parameter if you are specifying two it is the first and second and of course, so this is this should be yeah yeah 1.2 1.3 1.4. So, the default values is ok and it is just like whatever you show as the list of parameters you can just use equals and value to provide the default value and when you are calling that function if the default value is specified if the value of the parameter is not specified it is going to take the default value and if the value of the parameter is specified it will take that value ok yeah yeah. So, you are saying that suppose I declare another constructor which does not take any value as parameter then if you say this how will it know which constructor to call whether it is the constructor with the default parameter. So, the compiler will actually complain about that at that point and say that there is ambiguous there are two possible ways to call the constructor. I mean then maybe you have to rewrite this I mean if it is the case that in your program you will always know the value of v z but not v x v y and you can write the parameter list as first v z then v x v y, but if you have written first v x v y and then v z and if you want to specify a partial list of parameters that cannot be done. So, there is this yet another way of providing essentially this is doing something that you could do inside the constructor code, but this is done directly over here. So, what this says is that this is the constructor function it takes three arguments v x v y v z there are three data members x y z and x parenthesis v x means that when this constructor is called x the data member x should be initialized with the value of the parameter v x the data member y should be initialized with the value of the parameter v y and z should be initialized to v z. So, here you can say that I only want to specify z v z and not give x and y. So, the initialization list does not have to talk about every data member it can only talk about some data members how they are going to be initialized and then the rest of it is in the constructor code over here right or the rest of it may be uninitialized if that is how you want to keep your constructor and here this does not have to be just exactly the parameters that you passed you could put any you could say v x plus v y or any expression in the parameters fine. So, here is an example of constructors being used. So, this is the class point which we have already studied earlier it is a point in two dimensions as x and y and this is the constructor it takes two arguments and it sets the two data members to those two values right. It is the class disk which has a member center of type point and a member radius of type double and this is the constructor of the class disk and here I am taking three arguments x y and r right. So, this constructor takes three arguments three double valued arguments and here I am using an initialization list and the body of the constructor actually has nothing it has just returned right. In the initialization list how did I specify the values of data members data member and within parenthesis the expression in terms of the arguments. So, here radius r. So, this is saying initialize so in this constructor function when if this constructor function is invoked the data member radius of the receiver object will be initialized to the parameter r that is passed and the data member center right center is also data member of type point. The data member center of the receiver object will be initialized to whatever the constructor for point returns when it is passed x y as parameter. So, this is an explicit constructor function call for the class point right and we saw that when we do this basically an object of class point gets allocated the constructor on that is invoked with the parameters x and y and whatever that returns that is used to initialize the value of center the value of the data member center in the class disk. Is that clear? So, basically as you know this initialization values you can directly use parameters you can use expressions like x plus y you can even call other functions over there just like I have called a constructor function. But of course, those functions should be accessible at that point they cannot be private functions of some other class. So, are there any doubts about that right? So, these are basically different ways in which you can call in which you can pass parameters to constructors. One is through initialization lists and this is not about passing parameters this is really saying how the different data members are going to be initialized specifying default values right and using a constructor function explicitly. So, this will create an object of that class invoke the constructor on it, but you will not have access to that object directly unless you assign it to something. Is that clear? What does that silence mean? So, is at least this clear what am I doing when I am calling a constructor function directly? I am allocating an object and then calling the constructor on it. So, you know we have seen constructors and these constructors are basically called immediately after an object of that class is allocated and we have seen some ways in which we can sort of pass parameters or initialize data members of constructors. Now there are two special kinds of constructors that you know it is kind of important to study. So, one is this constructor which does not take any arguments. So, these are called default constructors. Constructor which does not take any arguments is called a default constructor. A constructor which takes arguments which could have default value specified for those is a non-default constructor. A default constructor must necessarily not take any arguments. Now, think of the situation where I am declaring an array of size 100 and each element in that array is an object of class v3. So, what we just said is that whenever an object of class v3 is created the constructor function will be invoked on that. So, when I am creating an array of size 100 where each element in that array is an object of class v3. So, some constructor function has to be invoked for each of those 100 elements. But the question is which constructor function should be invoked because I cannot pass parameters for each of these 100 elements for each of these 100 constructor calls. So, the convention is that the default constructor will be invoked. What is the default constructor? It is a constructor that does not take any arguments that is written without specifying any arguments. But the question now is that what if we had not defined a default constructor for a particular class, but I wanted to declare an array of that class. So, when I declare an array of that class for every element in that array the default constructor has to be invoked. But if I did not define the default constructor maybe by mistake or maybe by intention then what should happen? So, what happens is that if you have not defined any constructor if you have not defined any kind of constructor for the class then the compiler presumes that you have just been absent minded and you forgot to define a constructor and it will provide you a very bare bones default constructor. So, it will be a default constructor it will not accept any argument and it will not do anything inside its body it will just be an empty body. But there will be a default constructor and so you can now allocate arrays of objects because the default constructor is there to be invoked on each element of that array. And similarly if you do not provide a destructor the compiler will provide you a default destructor which also does nothing, nothing in its body. However, the more dangerous situation is here that if you have written a class definition and within that class definition you have written a constructor which takes arguments and you did not write a default constructor which does not take arguments. So, then the compiler cannot presume that you actually forgot to write constructors because you have actually written a constructor which takes arguments. So, then it will not provide you a default constructor. So, basically in our class v3 if I had provided this constructor, but not provided this constructor. It means that I was aware of the fact that constructor needs to be provided I have actually provided one which takes three parameters, but I did not provide a default constructor. So, in this case the compiler will presume that it is by intent that you do not want to have a default constructor. But if you do not have a default constructor, then you cannot declare arrays of this class because whenever you declare this class on every object which is an element of that array the default constructor has to be invoked. So, if you want to declare array of a particular class you have to define the default constructor for that class or you do not define any constructors and C plus plus will provide you a default constructor. You cannot say I am going to define a constructor which just takes arguments and no default constructor and then declare an array because then we do not have a default constructor which to apply. So, the best practice is to define default constructors whenever you are defining your classes. Put in a default constructor there so that even if you want to keep its body empty that is fine put in a default constructor. Now, just like default constructors have a special role for example, in allocation of arrays there is another kind of constructor which also has some you know important usage. So, if you look at this piece of code here I have a function and this is the main function. So, in this function I have allocated an object V of class V3 then I have assigned to V so this is an assignment statement I have assigned to V the object returned by a dot scale 2.0. And in the function main of course this is an object A of class V3 and this is these are the parameters of the constructor but look at this declaration here I am declaring an object A1 of class V3 and in the declaration itself I am initializing it to A. So, this is actually not an assignment statement this is an initialization in a declaration. Assignment statement looks like this something is assigned something semicolon this does not have that form. So, this is actually a declaration I was declaring A1 to be an object of class V3 and in the declaration itself I initialized it. So, if you look at this A or this A2 here I am saying allocate an object A of class V3 then call the constructor to initialize it with these as the parameters in the case of A and with nothing as the parameter in the case of A2. So, the default constructor will be invoked but this is a different situation right here I am saying allocate an object A of class V3 but initialize it with A. So, what I am trying to emphasize here is that these two things are different. So, saying V3 A1 and then saying A1 is assigned A is different from saying V3 A1 is A. These two are very different things here I am first declaring an object A1 of type V3. So, the default constructor for A1 will get called and then I am copying A to A1. Here I am declaring an object A1 of type V3 but I do not want it to be initialized by what the default constructor does. Here the declaration itself is saying I wanted to be initialized with A. So, this object will never have the original constructor or the default constructor invoked on it because it is not that I am not specifying how to initialize it I am specifying how to initialize it but this is not by means of one of those constructors. So, this kind of a situation where we basically have an initialization in a declaration cannot be handled by the constructors that we have just talked about and because this is not something where I first create an object A1 call a constructor on it and then assign A to it. This is saying create an object A1 and while initializing itself copy everything from A. The other situation is here. So, if you think about it here I am calling my func passing the parameter A and A is a parameter passed by value. So, how is a function call you know executed when I am passing a parameter by value the parameter is actually copied from the activation record of the calling function to the activation record of the called function. This is parameter passing by value right the value of the parameter is copied. So, here the object A has to be copied from the activation record of main to the activation record of my func when my func is invoked. So, therefore, in the activation record of my func when I look at this object which is the parameter this object has to get created but this object has to sort of be born by initializing with whatever I passed as parameter here it is not that first this object will get created and then somebody will copy this from here to here that object is created and at the time of creation itself I want this copy to happen. So, this is similar to what this initialization declaration happens and the third situation happens here when I am returning an object of class v3 from a function. So, this is once again how does a function return a value to its calling function it actually copies I mean that when the activation record of that is popped out prior to that the return value is copied from the activation record of the called function to the activation record of the calling function. So, now you know this A2 is my func A. So, this my func A is actually returning a value of class v3 is returning an object of class v3. So, this my func A which means in the activation record for main there will be an object of class v3 created and how is that object supposed to be initialized with whatever value is being returned from here and after that there is an assignment that happens over here. So, this is an assignment statement but my func returning a value which is basically a object being copied from the activation record of my func to the activation record is not an assignment statement you are creating an object to the activation record of main at the time of creation itself you want to initialize it with what is coming from the activation record of my func is this clear. So, these three situations function returning an object which sometimes may be optimized away by the compiler you know if it sees that whatever you are trying to do is going to be immediately assigned you know it might directly assign it to A2 it might not create the temporary object. But basically these are the three places when you are returning an object from a function when you are passing a parameter by value and when you are initializing an object in the declaration itself these are the three places where as soon as you create the object you have already specified how to initialize it. It is not through a constructor and parameters in that constructor that you are specifying how to initialize it. So, these three kinds of things actually require what is called a copy constructor. You are really trying to copy one object of that class to another object of that class at the time of its creation itself not as a subsequent step like this not as a two step process. So, this is not a case of copy constructor right because this is an assignment I have already created that object the default constructor has been invoked after that I am executing assignment statement. However, this is a case of copy constructor at the time of creation itself I want to initialize it. So, how do we write copy constructors? They are just like constructors so these are our usual constructors right same name as the class name and whatever you want to write within a copy constructor also looks very similar it has the same name as the class name because at the end of the day it is really like a constructor it is invoked immediately after an object of that class is created it is just that it is used only in those specific situations where you want to initialize it with something that you already know right and with an object of that class that you already know. So, therefore it is I mean since you want to initialize it with an object of that class it is not surprising that this takes as a parameter an object of that class itself right and here it takes this parameter by reference and this is not just an arbitrary choice what would happen if I wrote this copy constructor and instead said that this is this parameter is going to be passed by value what would happen is when I am calling this constructor function its parameter is passed by value. So, that parameter would need to be copied how do I copy call the copy constructor but then that copy constructor again requires the parameter by value how do I pass that value copy something which again will call the copy constructor right. So, it will lead to an infinite invocations of the copy constructor without achieving anything. So, that is why we need to pass this by reference. So, I need to pass an object of the same class because that is the whole purpose of a copy constructor it is trying to copy something at the time of creation of the object. But I cannot pass that object by value because in order to pass that object by value I would need to call the copy constructor itself again right. So, I have to pass it by reference and once I pass it by reference then this is just like any other member function like any other constructor function ok. So, that is the important thing about a copy constructor. So, and then if you did not write a copy constructor by yourself for your program then the C++ compiler will provide a default copy constructor. But all that it will do is it will just copy all the values from the object which you are trying to initialize with newly created object. It is like the usual assignment. But sometimes that is not good enough. So, for example, if you look at this example here I have defined a class string class my string which has a character array but I have not allocated this character array a priori I have not said it is a character of size 100 or something. It is just pointed to character and I will dynamically allocate this array and there is a data member length which gives the length of that string. Here is my usual constructor function and note what I have passed as parameter to the constructor function is not an object of class my string but a character array right because if I had passed an object of class my string by value it will again lead to an infinite sequence of invocations. But I have basically passed a character array here and then you can do whatever you want over here. This is the destructor function here is the copy constructor has the same name as the class name constructor at the end of the day. It takes an object of the same class by reference it has to take it by reference because it cannot take it by value otherwise there will be an infinite sequence of invocations. And I have also specified const here which means that whatever is being passed by reference cannot be changed within the body of that function. Because if you pass something by reference under normal circumstances you actually pass something by reference because you want to change it like the swap function we studied earlier. But here I am passing this by reference because I cannot pass it by value but I do not want the copy constructor to change anything of that object which I am trying to copy. So, I sort of prevent that by saying const over here. I have used the initialization list here saying the receiver object on which I am trying to copy basically the receiver object which has just been allocated and on which this copy constructor is being invoked its length data member should be set to source.length and then the receiver objects C array will be dynamically allocated to be an character of length plus 1 do some error handling appropriately if the new failed over there. Otherwise you copy all of the characters in source.C array to the corresponding elements of the receiver object C array. So, you see here that this copy constructor function is actually doing something interesting it is actually allocating a new character array. If I did not give this copy constructor if I just relied on C++'s default copy constructor all that the default copy constructor would do is it would copy sources C array to the receiver object C array but C array is just a character pointer. So, basically the sources C array is pointing to an array of characters the receiver object C array would just get that same pointer value. So, both of them would start pointing to that same array of characters and of course the length will get copied but both C arrays would now start pointing to the same array of characters if I use the default constructor because the default constructor is just going to copy the values from of the data members from source to the data members of the receiver object. So, both the character pointers would point to the same array. So, perhaps that is not what we want to do we really want to make a copy of that string and that can be done by this separate copy constructor. So, inside the copy constructor it is just like any other member function you can allocate dynamically allocate memory and do all of this. And this is one example of a copy constructor this is another example of a copy constructor from Professor Ranade's book where you are doing the same thing and there is some initialization lists that are used here and then within that you are doing something here it is not allocating an array but it is doing some other interesting calculation inside. So, is this clear? So, there are these two special classes of constructors we studied copy constructors and default constructors. Default constructors are absolutely necessary to define arrays. If you do not define a default constructor but define a non-default constructor for a class the compiler will not allow you to declare any array of that class because it doesn't know what to call on each object of that array. And copy constructors are really needed in cases where as soon as you are creating an object you know what it is to be initialized by by another object and that is where you need copy constructors and there are those three situations where you need those. Is that clear?