 So, today we spent last week essentially revisiting some of the basic concepts, now we get back to our discussion on classes, class, data members and member functions. We will begin with a review of class definition and usage which we did last time. There was a question asked by someone when we are discussing EZ windows as to how a function name is same as the class name and I had asked people to go back and look why the function name would be same as the class name. It happens in only one particular case, there is a special function which has the same name as the class name which is called the constructor function. There is another function which has a similar name with a tilde preceding it which is called the destructor function. We shall see what constructors and destructors are, essentially these are used to initialize objects which are instantiated by your definition. We will then look at the notion of a stack as a data structure. You are all familiar with arrays, but there are very many important abstract data structures such as stacks, queues, decks, linkless etcetera which make eminent sense for simplification of several algorithms that you write vis-a-vis the applications that you have in mind. So, using a conventional array directly in the solutions of such problems could cause a little bit of conceptual trouble. Of course, most of these structures are internally implemented using arrays, but you will create a level of abstraction by writing functions on these arrays which are related to the kind of data structures that you operate upon. We shall see an example of that when we will discuss the notion of a stack. In particular, we will define a stack of characters and then we will see how we can use this for editing text. Editing text is something that you have been doing always in the labs. For example, when you say g edit a file, what do you do? You see the text of the file on your screen and then you have a cursor somewhere. You can move the cursor left or right and at the cursor position you can insert some characters. At the cursor position, you can delete some characters. So, these are variety of things that you can do when you do editing. We shall see how to build a line editor in steps. A line editor is not a visual editor. You cannot see the text and cursor and so on, but you know that some text is stored in a file and you want to give commands like move the cursor to 85th character position, insert these many characters here, delete these many characters here. Such editors are called line editors. So, we shall see how exactly a line editor could be created using the abstraction first of stack and on top of it, additional abstraction for a class called editor class. We shall not be looking at the editor class today that we will discuss on Friday. So, we start with the review of class definition and usage. You will recall that last time when we introduced classes, we had taken an example of a simple class called an employee class. We had said that employees would be there in any organization and every employee would be regarded as an object belonging to the type class. We said that once we define properties of the class, these properties will apply to every object that is created for that class. The properties of the class are broadly divided into two parts. The first part is the data elements. In this case for example, when we say class employee, we notice that it has two data elements which are members of the class. One is a character string. So, it is obviously the name of a person and the second is salary which is rightfully a fractional number possible. Therefore, we call it float. We note specifically that these two member elements are not directly accessible to the programmer. In fact, if I compile these class libraries elsewhere or put them into a dot h header 5 and include them, I would not even know what are the names used for these data elements. I would not even know them. So, I would not see them at all. They are hidden much like the object that we discussed which is a cell. What is inside the nucleus cannot be seen by any outside element. It is inside. But of course, we need to operate upon these data elements and such operations are possible through member functions. We had mentioned last time that we can have two types of member functions, private member functions and public member functions. It is the public functions which are of interest to us because they operate. They permit us to operate upon the objects and they permit us mostly through parameters that we pass to these member functions when we invoke them. So, obviously the member function names must be known to us as programmers to be used in our main project. The implementation of the member function is usually included along with the class definition. We had not discussed private functions, but we had remarked that there could be private functions which like the private data members are not visible to us at all. So, we can never invoke them. However, they could be invoked in turn by the implementation of some of the public member functions. This is primarily to simplify the writing of the code for many of your public member functions which may otherwise become unwieldy. So, you might put some as private member functions. In this particular case, under consideration, we had defined this class employee with the name as one data element which is a character array of 60 characters and a salary as a floating point value. Then we had defined four public member functions. These four public member functions are put name, get name, put salary and get salary. The first one changes values of the data member element. For example, put name will take a name from us. Naturally, it has to be a parameter and since it has to be a character array, it is written here as star n m. Get name will check the value of the name inside the private element and return back that name as a string to us. In similar fashion, put salary will put some value to a salary which is the data element, member data element of an object and get salary will get it back. Of course, these are the function prototypes as you can see. The actual function implementations, these could have been written here itself directly, but as is standard with our programming practice that we would necessarily put those prototype name function definitions first, these would be defined immediately following this definition. So, these were some of the public functions that we saw. I have given here only two member public functions, the one which assigns a new name to the data element name. So, here star n m is the character string. I could have of course, put in a loop inside which will copy every character from array n m into the corresponding character position of name, but there exists a standard c string function which is strcpy which will copy this string on to that string and therefore, we simply use the strcpy. Notice that this will copy the second string into the first string and therefore, the value of name will be changed. So, notice that this function is the only mechanism of changing the value of the name, there is absolutely no other method. You have no direct access to name, name is a private data member of that class. To get the value out from any data element of a object, you have functions which will be get name and get salary. Here I have shown implementation of get salary which is perhaps the simplest of the functions. It simply says return salary. Remember, if you had defined a structure for example, in your program or if you have defined a simple variable salary, then you could have directly accessed salary. You could have said see out salary for any employee. You had put employees in an array, you could put salaries in an array and extract salary i for an employee i or kth or whatever. Now that means you have access to the member elements of the objects called employee. The object oriented paradigm hides that information from you and therefore, you have to do a little bit more of programming which is simplified by this function called. So, wherever you would have said for an object, let us say e 1 is an employee object which you have declared, then ordinarily if you had a structure, you would have said e 1 dot salary for referring. Here you will not say that, you will say e 1 dot get salary and that will get you the salary. So, actually a function is called, the function is invoked, the function looks at the contents of that salary value of the object and gets back it is essentially a message passing mechanism. When you invoke a function, what do you do? You are passing a message. The messages could be a variety of types. Some messages will change the value of private data elements. Some messages will sense the value of data elements and give them back. Some messages may do more complicated. These are the broad classifications. We shall see later that names like mutators etcetera are used to describe the functionality of Sulfon. Now, we will come back to the question that was raised last time. How come a function name for a class is identical to the name of the class itself? Should that not be prevented? Should that not be prohibited? The answer is that yes, it is prevented. If you have 20 functions which are defined as public functions for a class, ordinarily none of those 20 can have the same name as the class. But there is a special function which is called a constructor function. Let us look at the motivation for having a constructor function. In normal programming, if I declare variables, I can initialize them with values during the declaration. So, for example, I can say int m equal to 28 or I can declare float y equal to 23.52. Notice that this declaration means two things will happen. One, at the compiler time, the compiler will allocate memory to that variable and it will also put an initial value there. Now, just because we are looking at object oriented paradigm, should we lose this valuable asset or valuable function of being able to initialize values of a declared object just as we can initialize value of a declared variable. In fact, we can even initialize values in an array ordinarily. So, character array, for example, I can assign a string to that at the time of definition. I would like to have such facility. Indeed, such a facility is provided in object oriented programming through a special function called the constructor function. So, a constructor function, it has the same name as the class name. In fact, that is how C plus plus recognizes that what you are calling is a constructor. So, obviously, its purpose is limited. Its purpose is that it is invoked only when an object is defined or instantiated. It is not invoked any time later. And whenever it is invoked, it is capable of assigning initial values to the object. There are multiple forms of the constructor function. Different forms, we shall see two of them here. There is a corresponding function which is opposite of the constructor function. What is the opposite of construction? Destruction. So, there is a destructor function. And the destructor function has the same name as this function name preceded by a tilde. So, in case of an employee, the constructor function will be called employee. And the destructor function will be called tilde employee. In mathematics, tilde is often used to indicate negation. So, that is exactly the meaning here. It is negative of construction. So, if the constructor function is called employee for this class, the destructor function will be called tilde. Now, there is a major difference here that the objects when they are instantiated, which means at the compile time, the objects would be defined just as you define variables and arrays. At that point, the constructor function is invoked. Similarly, when you complete the execution of your program and get out of the program execution or what is more correctly called, whenever an object goes out of scope, we shall discuss the notion of scope later. At that time, the destructor function is invoked, which destroys that object. Essentially, it frees the memory that has been allocated to that object and making it possible for that memory to be utilized either by operating system for something else. Ordinarily, we understand that whenever our program stops execution, all arrays and variables, etcetera, etcetera, which are assigned memory locations will cease to exist and the memory will be returned back to the operating system. We shall see later that a destructor function, particularly the context of an object going out of scope, when we shall study the notion of scope, we shall see that objects can be destroyed even during the execution of your program. Much later, we will also see dynamic allocation of memory. In conventional programming, the dynamic allocation of memory for variables or arrays is done through m-alloc statements. m-alloc stands for memory-alloc. This m-alloc is not a compile time formulation. m-alloc is actually a function, which is executed during the execution of your program. Consider, for example, you want to create an array to store in one dimensional set of numbers, say 2,000 numbers. You have not declared it originally because you do not know whether you need 2,000 elements or 20 elements or 50 elements. Remember what we used to say? We declare some maximum size and use the remaining. C plus plus actually permits you to dynamically allocate a memory. While running the program, you can request the operating system. Give me 250 bytes. Give me 20,000 bytes. Such requests are made through m-alloc. We shall study these things later, but I am just mentioning it in the context of objects. Just as I can dynamically allocate memory, I can also dynamically create objects. So, once I have defined the class, ordinarily, just like simple variables and arrays, I will be defining my objects in my program itself. When I define them, at the compile time, they get created and they would get initialized if there is a constructor function. But I have a paradigm called new. When I say new, some object, then operating system gives me space for that object, creates that object and initializes any data elements, etcetera, etcetera, etcetera, which is similar to the m-alloc function, which I mentioned briefly. We shall study these things in detail later. As of now, we consider that once we define objects, once we define private data members, once we define public functions, which will include the constructor and possibly a destructor function, then we are ready to use that particular set of functions and values in our programs. Here is another example of a constructor. I have chosen to represent another class. This is a class whose objects consist of pairs of values. They are pairs. Each number in that pair is an integer. 3, 7, 25, 4, minus 8, 92, these are pairs of numbers. Ordinarily, there is no mechanism for me to represent such pairs, unless I use an array or two variables a1, b1 or some such thing. Object oriented programming easily permits me to do that by defining a class, which I have called tentatively as int pair to represent pair of integers. What are the data members of this int pair class? The int player class has two integer values, int n, int n. That is all. What are the operations that I permit on this pair of numbers? Here are the public functions. First look at the last function here, float ratio. Can you guess what this function would do? If you operate upon an object using this function, it should calculate the ratio, hopefully of m by n. Notice that while m and n are integers, m by n may be fractional and therefore, we expect it to return a floating point value, although the object data elements will be individually integers. Now, that is as far as the operation is concerned. We do not envisage any other operation other than setting the values to the function. So, I can say set int pair, which could be another function here. What I have described here are constructor functions in two different forms. The first form, which says int pair void means it will not expect any parameter. Now, there are m and n two data members. They have to be initialized to some value. Constructor is supposed to initialize them. If I do not pass any parameter, what values would it use to initialize? That is defined by the implementation of this function, which is shown here. Int pair colon colon, sorry, int pair colon colon, int pair again. So, int pair is this, this int pair is the name of the constructor function. This int pair is the name of the class. You remember this is how you define the member functions. Class name, colon colon, function name, parameter. Let us look at what this function does. This function merely sets m equal to 0, n equal to 0. Now, you understand why no parameter is required, because these are the default values, which somebody has decided that if an object is instantiated, if an object is created, then automatically it should get value 0 0. On the other hand, there might be instances where I want to create an object and give specific values to the elements m and n. Such a possibility is implemented by another variation of the same constructor function. So, notice that the construction function can be defined multiple times. This is one way of defining it. This is the second way of defining it. Now, we have said that each function must be uniquely understood. How can a same function name be defined at multiple places? How will we understand which function is being called? Well, that is understood by the parameters, which are passed to that function, which constitute the signature of the function. So, even though I have same function defined three different ways, each of these three definitions will have three different signatures, which will effectively be three different ways in which parameters are passed. Notice here that the first way has no parameter. The second way has two parameters. So, we know that these two are different and depending upon how these functions are invoked in your main program, the compiler will be able to understand which of these constructor functions is being called. Of course, there is a third function, which is ratio, which is actually the operational function that we have in mind. So, here is the float function int pair colon colon float ratio. Again, no parameter because there is an object. The object already has two values of the pairs of for the pair of integers and this is supposed to calculate the ratio of these two. Here, the ratio is being calculated. Notice that if I just said m divided by n, what would happen? I would get an integer division and the return value will be the integer. Since in general, integer divided by integer could result into a fraction, we have decided to return a floating point value as demonstrated by this word float here. And therefore, we typecast m and n independently into float and float. By writing in brackets a type name, whatever is the value that is written to the right of it, is changed in its internal type to the float. It is exactly like saying m multiplied by 1.0 slash l in an ordinary expression. What would happen? m multiplied by 1.0, 1.0 is floating point, m will be converted to floating point. And then, since the result is floating point, n will be converted to floating point automatically. Instead of doing that, this is a cleaner way of doing it. Yes, some question. Sit down, sit down, sit down. Yes. You can, why it is a explicit way of saying that there is no parameter that is given here. It is not number of parameters, it is also type of parameters. It is also the order in which those parameters appear. You know, when you say a signature, let us take initials of a name as signature. Now, Deepak Phatak, d p is one signature. Phatak Deepak, P d would be another signature. It is in that sense. Here is an example of the main program. Yeah. Let us look at it this way. These have no return data type, because these are initializers. Initializers won't return anything. Generally, the functions which are called mutators, which create some, which change some value, may not have any return. Unless you want to know whether something has successfully happened or not, for which there are other mechanisms. But things which change values, there are two ways of getting the return values, as you know, ordinarily. One by the single value, which is returned for which you define the type of that function. The other, if you pass parameters by reference, by sending pointers, then you will get back to it. All of those concepts holds good here. See, the only difference is that all this Jamela is being done, because the member data elements are not directly accessible to you. If they were, you could have done all those things in the program, as you normally do with variable. But that is also the beauty of object oriented program. It hides internal implementation details of the object from that subject. So, let us look at this particular main program. Here, I have defined two integer variables x as 25 and y as 7. I have defined a third integer variable z. Just look at this line carefully. I am instantiating two objects here, person 1, person 2. So, p 1 is an employee, p 2 is an employee, because sorry, p 1 is a pair of one pair of numbers, p 2 is another pair of numbers, because I am declaring them as members of the class int pair. So, these two objects are instantiated. Look at this p 1. When I instantiate p 1, since I have defined a constructor function without parameter, the constructor function would be invoked at this junction. So, what would be the internal private data members of p 1 will acquire as value? 00, because we had said 00 is the default. On the other hand, when we instantiate p 2, p 2 will be allocated, the data members m and n will be allocated values 8 and 6, because we have specifically said 8 comma 6. So, this happens to be a way of initializing an object. In fact, in e z windows, this is exactly what we had seen when we saw center, which was actually a class or position. So, the class and position itself was invoked as position as a function. It was nothing but a a creator function, a constructor function. Notice a dilemma here. I have said z is equal to p 2 dot ratio, opening bracket, closing bracket. Please note that ratio is always defined of two values, but here the two values are supposed to be the two private data members of the object under consideration. So, my invocation will simply be p 2 dot ratio, bracket, open bracket. This will calculate what ratio? m by n in a floating point value, but notice the problem here. After calculating the floating point value, going through all these Jamela, I am assigning it to z, which is declared as an integer value. So, what will happen? It will now truncate. I might as well have returned an integer value of m by n. This is a implementation problem. This is a mistake we are doing. What was the question? Loudly again. This is an important question. He is saying that in this ratio, I have not taken care of a situation where n is 0. What will happen when n is 0? It is determined exactly by what will happen under normal division operation when the denominator is 0. So, you will get not a value, not a number, infinity or whatever and you will get exactly the same thing here. You may get an error because of which the program may be terminated. That is another aspect of implementation. So, I was pointing out one aspect, namely that when I wrote this program, I goofed up in a major way by calculating a proper floating point value and assigning it to integer. This is not correct. So, what should be correct? I should not declare this as z, but I should rather declare this z not as integer. I should terminate this here and I should say this would be the correct declaration in the spirit in which the floating point is computed. This is one implementation defect. The other implementation defect is as pointed out by our friend there that look, I will have chaos if n is 0. I would not know what will happen. Clearly, when I do integer division in normal circumstances, I am expected to take care of it, not integer division. When division by 0, I am supposed to take care of it in exactly the same way. Whenever I define a function of this type, it is my responsibility because I am implementing this function. So, it is my responsibility to ensure that I should possibly check for the denominator and then implement the correct error handling situation. There is another purpose why I have chosen this integer pair as a class and I would like you to consider the following. You are familiar with arithmetic which is done on ratios of two numbers. Consider, for example, 1 by 3 plus 1 by 7. Each one of these two numbers, if converted into decimal fraction will result in recurring decimals, neither 1 by 3 nor 1 by 7 terminates. But suppose you were asked to add these two numbers, you would add them as 7 plus 3 by 21 which is 10 by 21 which may or may not be recurring and 10 by 21 will be the exact correct answer for the sum 1 by 3 plus 1 by 7 which means there is a possibility where I might require arithmetic to be done on such fractions. The fraction is always represented by a numerator and a denominator. Now, consider this int pair, this class is actually a fraction. Now, can I not define on such fractions, operations such as add fractions, multiply fractions, divide a fraction by another, subtract one fraction from another and I can construct a beautiful arithmetic comprising of fractions alone. How do I define these additional functions which will add fractions, multiply fractions, etc. I would like you to think about it. We will discuss this possibility next time when we expand the scope of our knowledge of functional. But you can see just as you can construct libraries of ordinary functions in the conventional programming, you can construct class libraries which can keep on expanding further and further. In fact, later on we will see a standard template library in C++ is an extremely powerful set of a whole lot of classes and their functions. We have already seen easy windows of the kind of graphic capability that it provides. We continue our discussion. First, we will try to understand the notion of a stack. Stack and queue are two very very important these are all abstract structures of data. You have studied array as the only structure of data but these are many more. A queue in a conventional sense would be known to all of you. For example, at a bus stop typically people will stand in a queue. What is the property of the queue? The first fellow who comes in stands near the bus stop. The second fellow joins the queue at the back. Third fellow joins the queue at the back and so on. So the queue increases in one line. But whenever the bus comes, the first fellow goes out. Of course, this is what you may call the description of a disciplined queue. In your mind imagine the typical Bombay queue that you see now. It is more like a heap of people all trying to get into the bus. Just like a heap of people try to get into the lifts here. I am amazed that you people at this level of maturity are not familiar and disciplined to have fundamental protocol of lift entry or train entry. The fundamental protocol says nobody even attempts to go in unless everybody in the lift comes out. This followed everywhere else in the world. Not in India and most certainly not in Iowa and you are directly responsible for it. So, sorry for digressing but this is a very, very important issue. It is as important as learning programming. Having discipline in your professional life and having discipline in your social life. Nobody even when the lift comes unless the lift is emptied completely or unless nobody is coming out, nobody should even attempt to go in. You know why? Because when you try to go in and inside people are trying to come out, the total time wasted is far more than the time spent in orderly exit and orderly entry. Now all of you are very intelligent people with scientific bent of mind and should automatically be able to calculate the loss of time and yet each one of you participates vigorously in increasing that time spent and the frustration. Sorry for digression but I get amazed every time I come here before I come out people are going in. Anyway, Q is not like that. So, Q is one person here, one person here, one person here. This is the head of the Q and this is the tail of the Q. So, people join at the tail and people get out at the head. This is known as first in, first out structure. So, there are many elements. What is the length of the Q undefined? If a bus does not come for half an hour, the Q may be a mile long. The Q might be empty immediately after the bus goes away. So, Q has a variable length of element. Of course, the element that we would be talking about would be numbers, characters or objects of any class etcetera. So, this is called the first in, first out or FIFO structure, first in, first out. We are of course not discussing this. We are discussing the stack. The most familiar example of the stack you would have seen probably in your hostel messes, the food that you served, you would have seen that the plates are kept in a stack. So, the stack is something like this plate here, another plate here, another plate here, another plate here and so on. So, the stack moves upwards and reduces downwards. Notice that at any point in time what is accessible is the top most plate on the stack. If there are 20 plates, can you say give me the seventh plate from top? Somebody will have to remove the top six plates, then only you have access to the seventh. In general, the stack is characterized by the fact that stack is accessible only at top end. It is not accessible anywhere else, unlike the Q. In the Q, people enter at the back, rear and get out from the front. Here, everything comes on the top and goes out from the top. The two functions associated with operations on stack of values or stack of elements are called pop, which is associated with taking out something, pop out of stack. And the other element is push, which is other function is push, which is associated with pushing it something inside. So, this is getting out, this is pushing, push and pop. How would you implement a stack or a Q? If you have to handle a set of elements, which are either numbers or characters or things or something, the obvious choice is array, because array is the only collection of values that you can think of. You remember we can have arrays of characters, arrays of integers, arrays of floating point numbers. We can have arrays of structures. So, complex things, you can have arrays of structures. In exactly the same fashion, you can also have arrays of objects. So, array is a natural structure, which we know how to handle. You remember, that is why we emphasize a very clean and correct understanding how to manipulate indexes for the array, i, j, k for matrices or whatever and also know exactly what we are doing. Of course, having done that, we feel very comfortable given an array. I can simply say j is equal to 125 and a j, which means go to 125th element direct. So, array permits you complete access to any element in the array. Queue and stack are restricted structures. We might use arrays to implement queue. We might use arrays to implement stack, but once we implement a stack on top of an array, the array is invisible to us. So, if at all we have an array and if at all we are going to define a class called stack or a class called array, that array will become the private data member of that class and therefore, it is not visible. What would be visible to you would be the functions which are defined for that class and these functions are pop function and push function. Consider, there is a stack in which there are elements a, b, c, d and capital M, some arbitrary characters, which is the element at the top, which is the position after M, where I can put a new element just one above it. If I declare an array, then I could say a 0 is a, a 1 is b and so on. So, the current situation as depicted here has five elements and they occupy in my array internally the positions a, 0, a 1, a 2, a 3, a 4. Obviously, the top position, which is the next available position, the top of the stack let me call it, is actually the sorry this should be 0, 1, 2, 3, 4. So, this position should actually be 5 because 5th element is ready to accept a value. If top of the stack is set to 5, if top of the stack is set to 5, then and if these are the elements of the array a, which contain the values as depicted, then you will agree that what this represents is actually the current situation of this stack. If I want to insert characters in this stack, what will I do? I will keep doing push operations, push on to stack, push on to stack. What will I push? Some character. So, what kind of function I will have to write if the name of that function is push in my main program somewhere I will be saying push let us say q. Please note that in my main program when I say push q of course this will be on some object called stack. So, let us say I will have to say s dot push q where s has been defined as an object. Notice that I do not even know what is that array internally that is used as stack. I do not know what is the current position there. I do not know how it is stack is implemented, but I would know that if I said s dot push and gave a character as a parameter, then this character q will go and sit here and the tops will be incremented by one to point to the next position. That is how I will have to implement this function. How would pop function work? The pop function will first reduce top s by one because top s is currently pointing to an empty place and will look at that array element and return that character value. So, the pop will return a character value, push will insert a character value in the stock and the stack is now managed internally by that object set of function or the class function. I do not have to do anything here. So, notice that no declaration of internal data members etcetera. Once I define a class called stack, once I define the member functions for the stack, then all is done. I just exercise the push and pop operations as I require and I will keep getting one value from the stack if I pop or keep putting one value in the stack if I push. You cannot. That is the whole point. No, you cannot. What is the use? That is a different matter. He is going back to the question. He is one person who is very comfortable with arrays. He has inserted a 0, a 1, a 2, a 3, a 4, a 5 by push operations and suddenly a brilliancy comes to his mind. He wants to change the value of a 1. He can do so very easily if he had an array. But in this case, he has no way to do that. The only way to change that value of ever is to pop, pop, pop, pop, 5, 4, 3, 2, pop, 1, change, push and then wherever you have kept these other fellows hanging, push, push, push, push, the only way. That is what is the discipline of the object oriented program. Once you say it is a stack, conceptually a stack does not permit anything else. Let me give you a more, an example which you can relate. Take that of a Q. Q can also be implemented in an array like this, where you have 0 as the front and say n as the n. If some fellow comes in, you make it n plus 1, n plus 2, etc. If some fellow leaves the front of the Q, say 0, you have to push everybody up. Now you say, no, but what if I want to change A5? In real life, how will you change A5? Suppose I am standing at the fifth person, fifth place in that Q and actually I am standing for a friend of mine. He comes after half an hour after having his breakfast, comes and says, thank you for standing for me. I will now replace you. So he is actually replacing A5 from FATAC by himself. That facility in a disciplined Q is not permitted. You try to do that in a developed country. They will trash both FATAC and his friend. It is not permitted, period. No questions are. That is the fundamental discipline of a Q. And exactly in the same fashion, this is the fundamental discipline of a stack. You cannot do any operation other than push or pop. Now what is the use? That is a different problem. There is obviously a use and that use is in the level of abstraction. Let me tell you another example which again you will be able to understand. You know that the computer at the operational level operates upon bits and bytes and you are able to do floating point operations. How are you able to do that? There is a discipline of definition of floating point as mantissa and exponent. If you wanted, you could actually take a set of bits and decide to do exactly what you want to do with them because bit manipulation instructions are available including in C plus. But if you did that you would be violating the discipline of floating point representation which has been agreed upon and given to you. Now why do you want to do floating point definition only add, subtract, multiply? Why cannot I shift left three bits of mantissa for example? Now that is a question that could be asked equivalently. The objective is of course if you want you can do that but that will be violating the norm of the definition of floating point. In exactly the same fashion object oriented programming makes it impossible for you to do anything. Please remember this always. Once certain functions for a class member functions, those are the only functions that can be used ever to do anything on that class object. Nothing else can ever be done period. That is the discipline. But we shall see how stacks are conceptually useful in an example that we will construct very shortly. Sorry? No, no, it is not discarded. Obviously I must write pop such that it returns a value to me pop. It is just like gate salary. For the employee class gate salary would return a salary value. Now obviously I must use it in my program somewhere. That is why I am getting the salary. That is the objective in fact of the pop. That is the objective. We will see that. We will implement these class very quickly here. So this is the recap of the definition of a stack as a programming object. Stack is essentially a container like container of various things in which values can be pushed in or popped out. It is first in last out or last in first out. Last in first out is the formal name to the behavior of the stack. It is called a LIFO stack. So LIFO principle last in first out principle. And it can be implemented using an array. So push always at one end and pop always from the same end. That is the beauty of this. Now what I am going to discuss is one particular implementation. There could be umpteen different ways in which you can implement stack or for that matter any such object class. There is a standard stack implementation which we shall discuss later which is part of C++ library. Here we will see the simple implementation. So here is the class stack. I am defining it using what I call compiler macros. Oh sorry. So here is the symbol s i z defined as 10,000. Then I have the include libraries. Now I am defining the class stack. Notice that the stack is defined as a char array s of size element. Notice also that size is predefined to 10,000. So there is no dichotomies. This definition is valid. Essentially then the private data members of the class stack which means private data members of every object of that class are two. One is a character array and other is an integer variable which is top s or top of the stack. Notice that both of them will not be visible to me. They are not visible to me. What are the public functions? Static int stack flag. Void init. Initialization of the stack but initialization of only top s to 0. We shall discuss that. I am not deliberately defining a creator function. There are multiple ways of doing these things but if I have not defined a creator function then initialization cannot be done automatically when the object is defined. I will have to invoke this function to initialize it. The most important functions as my friend pointed out there which will push a given character since I do not expect anything to be returned I have declared it as void on the other hand pop which has no parameter pop will go there and get a character back and the return value is defined as cap. So these are the member function prototype definitions. Let us look at some of the implementations. The push operation. The push operation would ordinarily would have said s top s is equal to c top s plus remember we said that top s is the next back end position. So the given character c which is the parameter here should be inserted into top s position and top s position should be upgraded by 1. This would have been the only statement here but just like floating point division could result in a division by 0. I might have a problem if my array size is exceeded compare the stack of plates which is kept in your mess 1 2 3 4 5 6 what is the maximum number of plates that can be kept well technically up to the roof beyond the roof the plates cannot go but practically much less than the roof because you would not be able to take the plate out from the top. So there is a implicit limit for every stack in our case there is an explicit limit because the size of the array that we have provided. We must therefore check if the size is already reached for example if top s is 10000 we know that the size of the array is 10000 so if top s has already reached 10000 it is beyond the existing capacity from 0 to 9999 which is what a 10000 element array will do and therefore I must take some precaution I am saying output an error message stack is full and then there is a return without any parameter because this is a wide stack so there is nothing is no value is to be return on the other hand look at the pop exactly the opposite may happen pop will ordinarily work using just these two statements top s points to the in the array top s points to the next available vacant position in the array so the current top position is actually 1 less than that in my implementation therefore I reduce top s by 1 and return s top s where s is the character array that I have defined so whatever is the top most element actually existing in the stack is taken out and is returned and this return is in tune with the care type that is declared so this is like my ordinary function so in my program when I have an object called s1 which is a stack 1 if I just say s1.pop bracket open bracket close that will actually be like a function call which will get me the next character from the stack and I can assign it to anything but here again I might have nothing in the stack everything has been popped out so if I say pop nothing will come out and that is indicated by the fact that if top s is already at 0 there is nothing there below that therefore I will have to say stack is empty these are the two main functions I can have additional functions for example the standard implementation also permits you to look at what is the element at top the actual element so you have another way of saying top it will not change anything but it can permit you to look at the top element but that is a standard implementation which we shall discuss later I am going to use these two main definitions and of course the definition of one way of initializing which says stack colon colon in it top s is equal to 0 what am I doing I am just announcing that even if that array contains some trash earlier I do not care my top s is 0 notice again that it is not at all required to initialize various values of the array at all but I am never going to use them I am going to look at only one element at a time and I am going to look at only that element which has been pushed by me unless something is pushed I cannot pop so there is no need to do anything else except to set top s to 0 which means the stack is empty now I wish to use this stack for editing text in a file so how could I do that ordinarily if you have a text hello world this is a text line and I say no no I do not like it I want you to say hello blank my blank what have we done we are trying to say that at this position insert character blank character m character y am I right if at this position I insert this character string I forget this edited version this position is typically called a cursor position in your conventional terminology you are all familiar with text handling editing and so on there was a time when visual editing of text was not possible that is because there were no terminals when we as students used to write programs here first we had paper tape on which we had to punch our programs and the machine would read the paper tape and will give a print out in text saying this error there this error there that error now I could not look at the holes of the paper tape and say where it is or I cannot I will have to do surgical operation on the tape to make correction if I want to change I to J I will have to close some holes and punch some holes impossible later on we had punch cards on a Russian equivalent of an IBM and again you can replace cards but it would be much easier if you have a 2000 line programs you read it in the disk line by line and then have some simple editor commands which will say delete line 4 go to line 10 7th character replace the 7th character by this or insert this word in the 54th position of line 123 these are called line editors they exist even now on your own machine for example there is an editor called V.I V.I is actually a line editor of that old vintage here what we are going to do is we are going to consider how would you implement a line editor for editing some text assume that hello world as a single word has been given to you or some text is given and I want one facility at a given position I want to insert something else or at a given position I want to delete something and first I want to go to a given position these are the three operations how do you edit in a text window in a visual way you will take your mouse and move the cursor to a position wherever it is for example here you will say move it here here and click so that that cursor line is there now whatever you type will get inserted there whatever you delete will get inserted from the left hand side whatever I want a similar operation but in a command driven fashion so essentially I want to be able to say insert something delete something or move the cursor to this position okay I can do all of this using an array to store all my characters what happens when I have to insert I will have to keep shifting first all the existing characters in that array downwards and then insert these new characters and I will have to keep track that while shifting downwards the array limit is not reached what would deletion means I would have to at the cursor position I will have to delete say 5 characters so that means all the remaining characters will have to be pushed up 5 characters and there is a chance that somebody will say at the cursor position delete 20 characters and there are only 17 above it I cannot delete 20 so I will have to take care of that error ordinarily I would write a single monolithic program to do all this using convention use of stack permits us to use a very special model for editing which is called a two stack model a two stack model says that I will use a left stack to store characters which are on the left of the cursor and right stack to store characters which are on the right of the cursor suppose my cursor is here at hello void then what will be the contents of L stack I will have here H E L O agreed these are the characters left of the cursor what are the characters right of the cursor void but W should be here O should be here R should be here L should be here D should be here so these characters should appear in the reverse fashion W, O, R, L, D are the 5 characters but the 0th character W is at the top followed by O because these things together these two stacks if you actually move them like this they should become the origins what is the beauty of this model at any point let us say cursor is associated with the left stack so tops will determine where the cursor is at the initial point you will take all characters and push them on to the right stack let us say all characters are pushed in the right stack in the reverse fashion so that means your entire text to be edited is on the right stack and left stack is empty if left stack is empty what is tops that is 0 which is equivalent of saying my cursor is at 0 because top of the left stack is the cursor so I will have internally a variable called cursor which will amount to initializing the left stack tops is equal to 0 if I say move cursor to 5th position what should I do I should pop 5 times from the right stack and push them into the left stack so my cursor movement simply consists of popping from one stack and pushing on to another stack or popping from this stack and pushing on to another at any point in time my cursor is always determining the current position if I want to insert 20 characters I may insert them on the left stack in the order in which they come that is insertion if I want to delete I can pop off characters from the left stack notice now that I can do all the editing operations that I want vis-a-vis my cursor position all that I have to do is whenever I insert characters by pushing them or whenever I delete characters by popping them off I will have to modify my cursor definition and bring it to a new cursor definition originally the cursor definition will be top ac I will tell you that this is considered a very clean model of editor two stacks and cursor is at the center let us quickly look at the implementation so I have stack L stack and R stack find char text 5000 out text 5000 I have just taken some 5000 5000 characters are a lot of characters by this 3, 4, 5 screen folds I have an old cursor new cursor, text length out text length I have an int i the sample text for editing this is just a sample what is the sample a, b, c, d, e, f, g, h, i, j, k, l m, n, o, p, q, r, s, t, w, x, y 26 characters are copied into the text which is the original text for editing the text length is string length so which will give me 26 I am just putting out a message that this is my editor now I say L stack in it R stack in it initialize stacks top s is 0 for both both stacks are empty cursor is at the beginning of the text initially so I have said that left stack will define my cursor push the entire text in the right stack first that is what my model was push the entire text on the right stack but how will I have to push in the reverse order remember the right stack should contain the characters as they will appear in the right order so the first element should be at the top second element should be next and the last element should be at the 0th element so notice how I am inserting or pushing text from text length minus 1 till it becomes equal to 0 in steps of minus 1 so if the text length was 26 I take the element number 25 push it first then element number 24, 23, 22 and then element number 0 so all my input text has been pushed on to the right stack now I set cursor to 0 edit flag we shall see where exactly we use this later I define an edit command I define an edit command and I define an additional array called add word which may be commensurate with one of some of the editing commands for example an edit command may be add and then I will give a word to be added an edit command may be move move may be followed by a number move 24 means move the cursor to 24th move 12 means move the cursor to 12th add word means add this add this given word delete 5 means at cursor position delete 5 character these are the possible commands that I can give later on Friday we shall examine how we can extend this to define an editor class and define editor functions and invoke it to build actually an editor but here we simply implement these functions so this is the trial code take cursor to position 10 and insert this before that position this is sensible I want to take cursor to 10th position and insert opening curly bracket 1234 closing curly bracket at that position so I have originally A, B, C, D, F, G, H, I, J, K, L, M, N, O, F, Z at that point I want to insert these characters what will I do I want to put the cursor to position 10 so I will define new cursor as 10 at this moment I don't know where my old cursor is it may be 0 because I have just come here or it may be 24 because somebody had moved it somewhere else so my new cursor position may be either greater than the current cursor position or less than the current cursor if the new cursor position is greater than the cursor that means my cursor which is the left stack I will have to take some characters from the right stack and put them on the left stack and put the cursor to the right this is what I am doing I am popping from the right stack and whatever character is popped is being used as a parameter to push in the left stack so left stack not push what I push what is popped out of the right stack so from the right stack I take out an element put it on the left stack and how many times I do that whatever is the difference between I will have to take new cursor to cursor of course my new cursor may not be greater than cursor it may be less than cursor if that is so what happens else shift characters to right stack from left stack exactly opposite so here I pop from the left stack and push on the right stack and this is executed from cursor to new cursor in steps of minus 1 notice I greater than new what happens if cursor and new cursor are same my cursor is position 10 and I now say move cursor to 10 no push or pop should happen you can examine this code nothing will happen the cursor will remain wherever all that we are doing after this is my cursor will now become the new cursor now I want remember the previous slide we have said take cursor to position 10 and insert this character string to the left of it so notice how I am doing it push characters from the add word to left stack so for I equal to 0 I less than string length of add word I plus plus those are the characters which have to push on the left stack all that I am doing is L stack push add word I each character will be taken right I have finished my editing I will just say out text length is equal to text length plus string length add word why because I added the add word so my total outstrain text length become so much more now I update the cursor value cursor is new cursor plus string length add word whatever was the new cursor position plus whatever characters I have added that is my cursor position I have finished editing but notice that at the end of finishing editing some of my text will be in the left stack some of my text will be in the right stack I have to reassemble the text which means effectively I have to move cursor to 0 so for I equal to cursor I greater than 0 I minus minus I push from the R stack sorry I pop from the left stack and push on to the right stack you see the simplest of the operation for editing cursor movement is push from one sorry pop from one push into another that is the simple cursor insertion push characters in left stack deletion delete characters from the left stack and then you can do variety of variations that you want to do ultimately I have to get text in the output string and I must extract it in again the now the order is right because I had inverted that order earlier so for I equal to 0 to out length which is the total number of characters that I have to extract I will skip popping from R stack from right stack and keep assembling in the out take first character goes to 0th position second character go to 1st position 2nd position and so on that is my output string so do you notice a clean and conceptually simple mechanism of editing a 2 stack model permits us to do that here are the execution results when I compile these I say a dot out text is this text length is 26 shifting all characters to write what to be added is this with length 6 I have given these messages these are typically called debugging messages as I have told you but this is to assert and that things are working well observe what happens shifting 10 characters to left stack so left stack now suddenly as a b c d e f g h i j adding characters from ad word which are the characters I am opening curly bracket 1 2 3 4 closing curly the out length is now 32 26 plus 6 shifting all characters from left stack to right the right stack already contained a b c d e f sorry the left stack what are the left stack characters the top of the character will be closing curly bracket remember the characters go to the left stack in the reverse order ok so closing curly bracket 4 3 2 1 opening curly bracket j i h g f e d c b a exactly opposite of this this is how the stack will have them the remaining characters on my right stack finally the output text it is the text that I wanted with this insert you you know now that the editor works so subsequently in the next lecture we will see how to extend this abstraction further I know now that a two stack model is a good model then I can now define an editor class and define editor functions where I can say I will define editor commands m means move cursor m 20 means move cursor to 20 add means add word d means delete word e means exit and now I can give a command so whatever you want to edit you say the text file to be edited you can read the entire text file into big array then you say give edit command so I will give edit command m 212 so the editor which is invoked should move that cursor there I say insert this delete this edit this whatever and I say at the end exit then it should reassemble all the edited text and put it back onto the file so that is we will see that in the next class any questions? thank you