 Hello and welcome back. We are continuing our study of object-oriented programming. And the topic of this lecture is Operated Overloading. Here is a quick recap of some of the relevant topics that we have already studied. We have been studying about object-oriented programming with structures and classes. We have seen how to access data members and member functions. We have seen the role of constructor and destructor functions. And we have also seen how function calls can be made with structures and classes. In this lecture, we are going to study how to customize operators for different classes. Specifically, we are going to look at operator overloading and assignment overloading as a special case of operator overloading. Much of this lecture is motivated by the treatment in the book and introduction to programming through C++ by Aviram G. Ranade published by McGraw-Hell Education in 2014. All examples taken from this book are indicated in the slides by the citation AJR book. Now, let's recall the class V3 for representing three-dimensional vectors that we have been studying over the last few lectures. This class has three data members named X, Y and Z, all of dive double and their declared private. It has several constructor, destructor and other member functions that we have studied over the last few lectures. For now, I am just concerned with this member function sum. This takes as parameter another object of class V3. This constant denotes that this object is not going to be modified within this member function. And what does it do inside this member function? It basically allocates a new object V of class V3 and sets the X data member of that object to the sum of the X data member of the receiver object and the X data member of V. Similarly, it does for the Y data member of V and the Z data member of V and finally it returns the object V. So, basically what this member function does when it is invoked on a receiver object is that it computes the vector sum of that receiver object with the parameter object that is passed. Now, recall also that we actually used the class V3 more in its struct incarnation to actually write a program about the simple motion simulator. And in that program, we had a simple simulation loop here in which at every simulation time step of granularity delta t, we were actually calculating the current displacement and the current position by using these expressions. What are these expressions saying? These are saying take the initial velocity as a three-dimensional vector, scale it up with t, the total time elapsed so far and add that as a vector to the scaled version of acceleration as a vector but the scaling factor is 0.5 t squared. Similarly, here add current displacement as a three-dimensional vector to the initial position as a three-dimensional vector to get the current position as a three-dimensional vector. Now, isn't this too clumsy? We wanted to do some simple vector scaling and addition but look at what we have ended up doing here. So, the question is can we write this in C++ in a slightly cleaner way as is shown here where I am just showing that I am trying to scale some things, add some things exactly as I want to do as vector quantities, as vector operations. Well, the problem with using plus and star for vectors is that normally plus and star operators in C++ do not operate on V3 objects' operands. So, the question is can we overload the meaning of plus and star operators to operate on V3 objects just like we want them to and the answer to that is a resounding yes. C++ indeed provides us a way of achieving this. To understand how this works, let us consider an abstract infix operator, act, act could be any binary operator like plus, minus, star, division, remainder, what have you. What do I mean by an infix operator? It means that when I use this operator, it is actually written between its two operands like I have shown here. Now, in C++ the expression x at y is considered completely equivalent to whatever you will get by applying a special member function called operator act on the receiver object x where you are providing the object y as a parameter to that member function. So, note that whatever appears on the left of act is the receiver object, whatever appears to the right of act is the parameter and for every infix operator act the receiver object class has a member function operator act. Note also that operator is a C++ keyword. So, now if we go back to our definition of the class V3, here is how we might implement the member functions operator plus and operator star. These are really fairly straightforward. So, operator plus takes another object B of class V3 as a parameter and it simply returns an object of class V3 whose x, y and z coordinates are the sum of the corresponding coordinates of the receiver objects and the corresponding coordinates of the object B. Similarly, for this scaling operation and in fact, if you recall this code that we have written here is really the same as what we have written earlier for sum but we have replaced some with operator plus. Similarly, here we have replaced our code for the member function scale that we had seen earlier in a few lectures back with operator star. So, that's all that we have done. It's also important to note that these member functions are not going to change the receiver object and it's very important to denote this very explicitly by writing const after the parameter list and before the opening brace. So, now if you look back at our motion simulator code we know that these two stars are taken care of. This will be well dot operator star applied on T and this will be acceleration dot operator star applied on T square, but what about this? In order to interpret this I would need to apply 0.5 dot operator star applied on this but clearly that doesn't make sense. 0.5 is not a receiver object of class V3. So, what do we do about this? Well, C++ provides another overloading technique to solve this problem. For every member function operator at that you can define within a class C++ also allows you to define operator at as a non-member function as a simple ordinary function that takes operands and returns a value and once we have done this we can once again use at as an infix operator in expressions. So, let's look at the simple example. Here I have written operator star not as a member function of any class but just as an ordinary function it takes two arguments and returns a value and this is the computation that it does inside. The important thing to note here is that the order of the typed operands is factor which is of type double comes first and then B which is of type V3 class V3 comes next. So, once I define operator star as an ordinary function with the operands appearing in this order I can now go ahead and write an expression like factor star B. So, on the left hand side of star I have the parameter that comes first and on the right hand side of star I have the parameter that comes second and what do I do in the body of this ordinary function? I actually invoke the member function of this object B specifically the member function operator star of this object B and to that I pass factor as a parameter. So, effectively I am computing factor star B by evaluating B star factor and of course this is possible because of the commutativity of star when you are scaling a vector by a scalar constant. So, now if you look back at our code these two stars are basically invoking member functions by the name operator star this star is actually invoking the non-member function by the name operator star. Well, which are the operators that can be overloaded in C++? Well, almost all operators that you really care about and here is a long list of binary operators and unary operators that you can overload exactly in the same way that I showed for star and class interestingly note that there are several assignment operators also that can be overloaded. Now, this is particularly interesting because unlike several other operators the assignment operators already defined for all kinds of classes and structures. So, for example, here if I have two objects of class B3 and if I say B is assigned A I know exactly what to do C++ compiler knows exactly what to do all the data members of A will have their values copied to the corresponding data members of B and this whole B assigned A as an assignment expression will evaluate to the value of A. While this is true that assignment is really defined for all classes and structures but you may want to redefine the assignment operator for a certain class or structure for some specific computation that you might want to do and this can be done by defining the member function operator equals. So, whenever we want to write an assignment expression LHS is assigned RHS. As an assignment expression this will be considered by C++ to be completely equivalent to the result of applying the member function operator equals on the LHS as a receiver object with the RHS as a parameter. So, note the left hand side is the receiver object right hand side is the parameter and the definition of the member function operator equals is really going to be very similar to the copy constructors that we have seen earlier except that we must remember to also return a value because every assignment expression must have a value. So, here is a simple example of assignment overloading taken from AGR book we have a simple queue here which is trying to keep track of waiting entities perhaps waiting cars the identifiers of these entities are stored in this array elements starting from the index front the next n waiting elements starting from the index front store the identifiers of the waiting entities and we are going to assume that the indexing is circular or modular so that once the index reaches 100 it wraps around and comes to 0. Well, you could have several member functions for this class but right now we are interested only in this assignment overloading member function operator equals like a copy constructor it takes a reference to an object of the same class as a parameter and we have used const to denote that the RHS cannot be modified by this assignment overloading and the assignment overloading must return a value so here it is returning a reference to an object of the same class remember that this operator equals member function is going to be invoked on the LHS of the assignment as a receiver object so here we take the data members front and n waiting of the receiver object that is the LHS and assign them the values of the corresponding data members of the RHS object then we go around a simple loop in which we see the values of the elements array of RHS to the elements array of the receiver object that is the LHS and which are the elements that we copy starting from front the next n waiting elements are copied here and of course we use this circular or modular indexing at the end of it this member function says return start this what do we mean by this well in C++ inside any member function of any class this always denotes a pointer to the receiver object so here this denotes a pointer to the LHS of the assignment so start this is a reference to the LHS of the assignment so that is what is being returned by this assignment operator so in summary in this lecture we studied about operator overloading in C++ is a programming convenience and we also studied about assignment overloading as a special piece of operator overloading thank you for your attention