 Hello and welcome back. In this session, we are going to try to put together all that we have learned about polymorphism and virtual functions into one exercise to build one interesting program. So, here is a recap of what we studied in the last lecture. We studied about polymorphism in C++ programming. We studied about virtual destructors and abstract classes. In this lecture, we are going to put all of this together to write a simple example program on polymorphism. Much of this lecture is motivated by the treatment in the book and introduction to programming through C++ by Abhiram G. Ranade published by McGraw Hill Education 2014. In fact, the example that I am going to show you now is taken from this book. So, here is our problem statement. We want to write a C++ program that takes as input a string which is going to be a verb, an English language verb from the user and it is going to print the past tense of this verb. So, here is how we might go about trying to solve this problem. So, we will classify verbs into two major categories for purposes of generating past tense. So, these are regular verbs and irregular verbs. A regular verb is one where you can just take the string that represents the verb and suffix ed to it to get the past tense of the verb like play, played, walk, walked, look, looked, watched, watched. Irregular verbs on the other hand are verbs where you cannot do this to get the past tense. For example, be, was, speak, spoke, eat, ate. So, the question is how are we going to do this systematically in a program? So, well, we might say that we are going to keep track of what are the regular verbs and what are the irregular verbs. For the regular verbs, we can just suffix ed whenever we are asked to generate the past tense, but for irregular verbs, we have to store the past tense along with the verb and if we are asked to generate the past tense of one of these verbs, we can just read out from the stored past tense form of the verb. So, as a programming solution, we are going to have a class verb which is going to represent all verbs, but as we just saw in the last slide, it does not make sense to just talk about a verb. We are going to talk about regular verbs or irregular verbs for purposes of generating past tense. So, while we are going to have this class verb, it would be good to have this as an abstract class. We do not really want to instantiate an object of the class verb. This is meant to be the base class of a class of regular verbs and similarly a class of irregular verbs and as you can see here by declaring a pure virtual method in this class, I have basically rendered this class abstract. What does this class have as its members? It has a protected data member called root which is a type string and it has a public method called get root that accesses the protected data member and returns it. Here is what a derived class of regular verbs might look like. This class is derived from the base class verb. This is the constructor. The constructor for this derived class takes a regular verb as a string and it stores that regular verb in the root. If you recall, the root was a protected data member of the base class. So, it can be accessed inside the derived class and then there is this public member method past tense. What does it do? It is going to return the past tense of a regular verb and this is the easier case. It can just return the string that was stored in the root which was the actual verb concatenated with ed. If you recall, this plus operator is concatenation for the class string and so here this will return the string stored in root followed by ed. So, this is the simple case. The regular class of verbs as a class derived from the class verb. Here is the other derived class irregular which is also derived from the class verb. Now, if you recall for irregular verbs, we said that we are going to store both the verb and its past tense. We did not need to do this for regular verbs. So, for regular verbs, I did not have a special string storing the past tense, but for irregular verbs, I will have to do that. So, here is the string that is going to store the past tense of the verb. Here is the constructor of the class irregular which is going to take two strings as arguments. One is the verb, the other is the past tense of the verb. It is going to store the verb in the root and it is going to store the past tense of the verb in this private data member pt. So, when I instantiate an object of the class irregular, I will have to pass these two parameters and these two parameters are going to be stored in these two data members, one of which is specific to the class irregular only. What does this method past tense do? In this case, because it is the irregular class of verbs, I cannot concatenate ed and return the past tense. So, I have to just access the past tense of this verb which is stored in this private data member pt and I have to just return that. So, here is how our overall solution might look like. Here is the main function. In this main function, I have an array of regular verbs. This array is of size 2. I have instantiated it with two objects of the class regular. Each object has been created by a call to the constructor of the regular class with an appropriate string for the verb. So, here the two strings, the two regular verbs which are being used to instantiate the two objects in this array r of size 2 are play and watch. Similarly, I have this array i r of irregular verbs. This array is of size 3 and I am going to instantiate this with three objects of the class irregular. Each object is obtained by invoking the constructor of the class irregular with appropriate strings past as arguments. Recall that a constructor of the class irregular requires the verb as well as its past tense to be passed as arguments and so that is what we have passed as arguments here. Here is v1 which is a pointer to the base abstract class verb and here is our query string. We will see how we are going to use this v1 in the subsequent slides. Here is our query string and we will write a do while loop here and inside this loop, we are going to ask for a verb to be provided by the user as input and then we are going to search these two arrays and if I find it in this array, I will concatenate ed to it to print out its past tense or if I find it in this array, I will pick up the past tense from the appropriate data member of the irregular verb object and I will print that out as the past tense and finally, this main function returns 0. So, let us now see what happens inside this do while true loop. Note that this looks like an infinite loop here, but we will see that in the body of this loop, we can have statements which are going to print out whether we have been able to find the verb and therefore, what is its past tense or whether we have not been able to find the verb, it does not exist in the knowledge base that this program has and of course, in order to come out from this loop from this infinite loop, we can always terminate the program by pressing control C for example, from your keyboard. So, let us see what happens within this do while loop. So, here is the do while loop, I am going to ask the user to enter the verb to find, I am going to read that in and store it in the string variable query, I am going to set a flag to false. After that, I am going to loop over the list of regular verbs, I know that that has just two entries. So, here is my for loop iterating over those two entries and note what I have done here, if you recall, we had declared a variable v1 which was of type pointer to the base abstract class verb, I am now going to use this pointer variable here to store the address of the ith element in the array of regular verbs. Now, the ith element in the array of regular verbs is of course, going to be a regular verb. So, the address of that is going to be the address of a regular verb, but since a regular verb is derived from the base class verb. So, this can also be viewed as an address of an object of the base class verb and therefore, this assignment is fine, but remember also that the base class verb was an abstract class, it had if you go back here and see, you will notice that the base class verb had a pure virtual method therefore, it is an abstract class and therefore, whenever here I am going to make a call v1 arrow something, v1 arrow something, it is actually going to find out what is the actual object to which v1 is pointing and invoke the appropriate method from that derived class. So, let us see it in action over here. So, what we do is we say if v1 arrow get root is query. So, once again v1 is an abstract class. So, v1 arrow get root is actually going to invoke get root of the class by first finding out what is v1 actually pointing to here, v1 is pointing to an object of class regular verbs. So, it is actually going to invoke get root from the class regular and that is going to return the string that is stored as the verb in the first element of this array and if that matches query, we are going to say past tense of that string is and we are going to call v1 arrow past tense. Remember, v1 is abstract class in which past tense was declared as a virtual function. See, this past tense was declared as a virtual function. So, when I say v1 arrow past tense over here, it is actually going to find out what is v1 pointing to, v1 is pointing to an object of the regular class and so, it is going to call past tense of the regular class and what does past tense of the regular class do, it just returns the root concatenate with ed. So, that is what it is going to return over here. It is going to print that out, print an end of line, it is going to set the flag found to true and break from this for loop because it has now found the queried verb in this list of regular verbs. So, this is the end of the for loop searching over the list of regular verbs and if it did find this verb to be within this list of regular verbs, then it will again continue which means it will go back to the beginning of the loop and again ask for the next verb to find and again restart the whole process. However, if it did not find the input verb in this list of regular verbs, then found would be set to false because note that it was initialized to false and it is set to true only when I have found the regular verb in this array of regular verbs. So, if I do not find it found would still be set to false. So, this if found is true then continue this statement would not be executed. In fact, what we will now do is we will now go and search for the list of for the queried verb in the list of irregular verbs. So, once again this is a very similar action that happens here because the array of irregular verbs has three entries in it. So, I am going to have this for loop which iterates from i 0 to i less than 3. Once again I am using the same pointer v 1 of the base verb class to point to an object from this array of irregular verbs. So, this is really an address of an irregular verb, but because in the irregular class is derived from the base verb class. Therefore, an object of the irregular class can also be thought of as an object of the base verb class. Therefore, an address of an object of that irregular class can be thought of as an address of an object of the base verb class. So, this assignment is fine and then here I am going to do the same thing as I had done earlier I am going to call v 1 arrow get root. So, if you go back in the class v 1 there is this method get root which is declared and it is not virtual. Therefore, v 1 arrow get root will actually invoke this method and it will return the root verb stored in that object and if that matches the query then we will print out past tense of root is and we will print the queried verb over here. And how do I now print the past tense of this verb we call v 1 arrow past tense, but v 1 being a pointer to the base class and the base class being an abstract class in which past tense was a pure virtual function. Therefore, v 1 arrow past tense would really require us to find out what is v 1 pointing to and in this particular case v 1 is pointing to an object of the class irregular. So, therefore it has to go and call past tense from the class irregular and this method past tense in the class irregular is just going to return the string p t which was the past tense of the verb that was provided when this object itself was created and to the constructor of this class we had provided this past tense as an argument. So, that is what it is going to return here and it is going to print that out set the flag to true and break from this for loop because it has found the queried verb in the list of irregular verbs. Of course, if we have not found it either here or here in the list of regular or irregular verbs then found is false because it was initialized to false over there and then we can say verb not found and we can go back and ask for the next verb. So, as you can see this is truly an infinite loop where we keep asking for a verb see whether it is in the list of regular verbs if so we print out its past tense by invoking the past tense method of the derived class regular and if it is in the list of irregular verbs we print out its past tense by invoking the method past tense in the derived class irregular and I have used the same pointer v1 which is really a pointer of the base class verb to point to both objects of the array R which are really objects of the class regular and also objects of the class irregular which are entries in the array I R and when I invoke v1 arrow get root either here or here this really goes and invokes the method get root which is not declared to be virtual in the base class verb but when I invoke v1 arrow past tense either here or here because past tense is declared to be virtual in the base class verb here I have to find out what is the context in which this method is being called I find out that here v1 is pointing to an array of class irregular so the past tense of the class irregular is called here v1 was pointing to an object of the class regular so here the method past tense of the class regular is called so here is how our overall solution looks like inside the while loop inside the do while loop so here is how the sample output might look like here we have highlighted the verb and the past tense of the verb using bold face in reality when you run the program on your console output everything is going to appear in the same font so if you enter play then play is going to be found in the list of regular verbs remember we had initialized the list of regular verbs with play and watch so play is going to be found there and it will say past tense of place played if I enter go then because go was already used to initialize go and went was already used to initialize the array of irregular verbs so it will find it in the array of irregular verbs and it will say past tense of go is went similarly past tense of speak is spoke but if you enter have then note that have was neither here nor here and therefore we will encounter this case where it is verb is not found in both the lists and it will print out verb not found and again it will go back to the beginning of the do while loop and ask for another verb and here if you say watch here it will find it in the list of regular verbs and it will print out watched and then you can of course press control c from your keyboard to come out of the infinite loop so in this session we actually saw how to write a complete program that does something interesting it reads a verb from the user and it prints out the past tense of the verb and in our program we actually applied some of the techniques of c++ programming that we studied in the last few lectures specifically we made use of polymorphism we made use of virtual functions and in particular we used pure virtual functions and also abstract classes so of course you can write a lot more other interesting c++ programs using all of these concepts have fun programming with polymorphism thank you for your attention