 In the remaining time of this class, we would be revisiting the notion of functions. Before that, I want to again review the, not review actually introduce the concept of a constant qualifier, a constant qualifier. Once we look at the constant qualifier and the function prototype, we will continue to discuss classes and how to construct classes. You will remember from last lectures that we have looked actually at two classes. Now, what I will be doing by the way, not only in this lecture, but in the rest of the course, I will actually be following Kuhun's book. This is to ensure that you have a material to read after you go back home. So, I will be discussing problems and I will be discussing explanations of the features from Kuhun's book. Usually, the class description that we will be discussing today belongs to chapter 8 of Kuhun. But usually, there will be some attendant issues which are related to that discussion. What I will do is every time I refer to those, I will mention the corresponding chapter and section of the Kuhun's book, so that you can refer to that portion when you go back and read up something. So, first what I discuss of course has nothing to do with Kuhun's book. It is a general discussion. Let us look at the constant qualifier first. Usually, whenever you have your variables, the variables can change in value. The only thing that you are familiar with which has a constant value is actually not a variable, but a symbol which you define as a part of the pre-processor macro-deferences. So, for example, if you say hash defined max as 100, then we know that wherever the word max is used in your program, it is actually replaced by string 100. So, it is not really a constant value of a variable, but it is actually a text which is changed. Many times, we would like that when we say, for example, int m, we are permitted to declare an initial value for that int m. So, I might say int m equal to 500. Now, what I want is that while I might have other ints, say int kl or whatever, I might change the value of k sometime like this. I might change the value of l as equal to k star m or whatever, but I might also change the value of m which may become say 200. All these are permitted statements because klm are normal integer variables and their values can be changed. If I wish that some of these variables should not change their values during the execution of the program, they must remain fixed to the initial value that they have been allocated. If I want that to happen, then what is the feature that I have? That feature is called the constant qualifier. For example, if while declaring this int m, if I said constant int m equal to 100. Now, this tells the compiler that while I want m to be a variable, that has to be allocated space and value 500 has to be given there, but this value 500 should never change during the execution of the program. If later the compiler finds a statement of this type m is equal to say k plus l or whatever, it will flag this as an error because you are attempting to change m which has been defined with a constant qualifier. Now, this is your way of defining not through a macro which replaces text inside your text while compiling, but through a variable. These constant definitions are useful whenever you are passing parameters to functions which are passed through reference which means that you would get back the corresponding parameter if it is changed in the function. You may want to ensure in the function that a certain parameter which you have received while it might have been a pointer and you are entitled to change that value, this function should not change the value. You want to ensure that some parameter should not change the value, then you can use the constant qualifier in the formal parameter. When you say some parameter is constant, what it means is independent of who has called it how the value of this parameter will not change in the function that is the objective. Let us look at functions and prototypes. You are all familiar with the fact that in my program I can write let us say I want to write a function. You all understand this main program? In this main program I have declared two protein point variables y and r. I am collecting the value of y as input and then I have an expression r is equal to f in bracket y plus 3.416. You look at this program from a compiler's viewpoint. While compiler is compiling this program it will come to this particular point this particular expression and start looking at f in bracket y. The compiler has two options either f is an array in which case yth element could have been referred to, but then it should have found a square bracket. So, it is obviously not an array. Then this must be a function that is how the compiler concludes that this is a function. During compilation it finds out that f must be the name of the function it must be returning some value which is valid for this expression evaluation. This value could be integer this value could be real it does not know what that return value is. However, it knows that this y has to be a parameter which will have to go to that function and this y is flow. At this juncture it must know the function definition to resolve these two issues. A whether the parameters that are being passed to the function are correct. There are two three parameters and they are in right sequence in the right type or not. And B what is going to be the return value because then only it will be creating a place for holding that return value and using it properly. That is the reason why you write your function definition before the main problem. So, that the compiler will know what that entire option is. So, here for example, I might write a function which will say float f. Can you understand this function? It is a simple function. It is actually finding out the value of 20.94 x square for any given parameter x. So, you understand now how this function will be compiled and used during execution. There is no problem here in this main program whenever f of y is called this y as an actual parameter will go and get copied into this x which is internally a formal parameter for this function. I have declared float result in this. The result will be calculated and the result will be written. It is in line with the description float f which means the return value is floating point and that value will come back here. If I write this function here and if I write the main program here, then the compiler understands fully everything about it needs to understand. It in fact also understands how the function is computed because this entire code is given here. Now, this way of writing function ensures that you have written two important things about a function at a single place. What are the two important things? One is the function definition. The first line a function definition needs to define what is the return type of value that the function sends and what are the parameters that the function expects. There may be 3, 4, 5 parameters, some parameters may be a care array, some may be integers, some may be floating point and we are already familiar with the fact that the order in which these parameters appear is important because the corresponding parameters will come from the calling program and sit there. One thing I would like you to again understand that as far as the compiler is concerned, the compiler needs to know only the function definition while compiling the main program. Whether it is calculating 20.94 x square or whether it is calculating 33 x cube or whatever is immaterial for compiler that is part of the implementation. So, all of this is function implementation. So, we must appreciate that there are two parts of a function writing, a definition and implementation and that the definition is required while compiling your main program. Without the definition the compiler will not know what is the name of the function, what value it returns and what are the parameters. Given this C plus plus permits you to separate out these two parts while you write your problem. So, you can write only the definition at the time of writing your main program and you can write the implementation anywhere that you want. How is exactly this handled? So, let us understand this. If I write this at the top and then start writing into main, this is considered perfectly valid because for compiler the only thing required to know is name of the function return value and parameters. This is called a function prototype. Of course, the body of the function which implements the function has to be written somewhere. In normal practice the option given is after your main program ends, you can write again the float function f etcetera etcetera and write the entire implementation. Of course, you have to repeat that function title in order to implement, but it is possible that this entire implementation is written separately. The entire implementation is written separately. There are two things about prototype and implementation separation and prototype writing that you must traditionally know. First, this prototype definition is a detailed definition, but whatever I have written here as float x can also be written more simply as float f. Please note that this is also a valid prototype definition. Why? Actually in prototype the physical location where the parameter value is to be copied is not relevant. That will come in the definition of the implementation, but for compiling what it must know is that it has one parameter and the parameter is float. That much is sufficient. That is why you will find in many examples, the prototype definition does not contain a name of a variable or an array or anything. It just contains the type of value that it is supposed to receive, which is adequate from the point of view of compiling. The detailed explanation of this would be detailed writing of the variables arrays etcetera must happen subsequently. Now, consider as I said this implementation could be separate. Usually the implementation is given immediately after the declaration of the function name. So prototype and implementation are together and in such cases you must use the first version of the prototype definition namely this version if you are writing the function implementation there itself, but if you are separating this prototype is open. Now, how does the separation work? The separation has two components as I said the function definition and the function implementation. Let us generalize this to say the following. I have written a program in which I have three function prototypes defined. Notice here that the second function that has been defined has an array int array. If I just said int it will assume that a single value has to come. Int array implies what? Int array implies that it will receive a pointer. A pointer to the 0th element of that array I could have very well written this simply as int star because that is a pointer. So that is if I want to indicate that I receive a pointer I will have to say int star, care star whatever. If I am implying that it is supposed to receive a variable I have to give just that type that is the prototype definition. Now, we talk of the separation. These prototype definitions f 1, f 2, f 3 that you see will generally result from the fact that some other people let us say my colleagues in my lab batch have written these functions. These functions will exist in their own directory. When I am writing my main program I may not have those functions. So I may if I have such 20 functions I will have to list these 20 functions. If another friend is writing another main program that person will also have to list these 20 functions. Not only that for the correct execution I will have to also somewhere compile the implementation of these 20 functions as well and collect everything together. The separation permits me to do two things. First the separation of these prototype definitions. These can be separated out and put inside sorry put inside a header file all of these just the function definitions. I can put them in a header file and when I put them in a header file I can put here a single statement which says include you would have seen some such includes in some of the program that you wrote. The idea is that when I write my main program I know I am going to use one of these 20 functions. I do not have to write all those 20. Somebody who has written these 20 functions has collected the definitions of the prototype separately which is called fund dot h let us say as long as I include that that is when I include it using double quotes. The convention is that the operating system will first search in the current directory in which I am compiling my program and if it does not find it it may go to the include directories which have been defined. We will have a separate discussion on what compiler directives to give for such inclusion as well as the inclusion of library compiled functions which I will just mention in a moment. So this is the first separation that means I do not have to write any one of these. What about the implementation of the functions ordinarily these implementations would have come here function one function two function three and this could be let us say 100 lines of C plus plus code each function 20 lines 30 lines etcetera and I would be forced to include that and compile it. But if these functions have been written by someone else just as that someone else has created fund dot h someone else could create a separate file called fund collection dot CPP let us say this fund dot CPP does not include main program it has only these 20 function implementation the logic 23.4 multiplied by x into x etcetera that function definition. Now ultimately my program which is the main program has to be compiled with the function definitions all right but when the program is to be converted into an executable file it should have the compiled versions of these functions also linked to it. There are two options of doing it just as I include fund dot h I can also include fund dot CPP then the fund dot CPP in the text will be included and everything will be compiled together and an executable will be formed. The other option is compile these separately but create a file called fund dot o not a dot out file a dot out file cannot be created because there is no main program but I can give a compiler directive which we shall study later by which I can tell the compiler kebab compile these 20 functions but do not attempt to produce a compiled version produce a dot o version. In fact a dot o version will be produced for every individual function that you have you can compile each one separately or compile a collection you will get a dot o file. Now this dot o file is the compiled version of the functions I now suddenly have the following choice first I will say fund dot h and I will say include fund dot h so I do not have to write all of the fund dot h is included which is the definitions of the function then I write my main program and after come ask afterwards I give the compiler only my main program and the function is independent. So when I say c plus plus but this time I will say do not produce an executable version in fact you cannot because there are functions whose implementation is not known instead produce a dot o file of my main program. Assume that this all this process produces a dot o file sorry it produces a file a dot o this is different from a dot out a dot o is a compiled version but not ready to run but for doing that I do not require anything about the functions. Now I can ask the compiler that the a dot o file that you have produced in the first phase please link it with fund dot o and then produce a dot o. So a dot o plus fund dot o should give me a dot o this feature is available with all same c plus plus compilers the linking phase is the phase where such linking happens. Those of you who have attempted to run e z windows will know that when you write e z windows programs you have the include something dot h something dot h files at the top then you write your main program but where are the actual complete class implementations you have not written them you are not including anything for the class definitions and yet the program works how it works is when you compile you do not say normally c plus plus api you compile it using a special script called compile script have some of you seen what is there inside that compile script compile there is a command api compile or compile which actually has c plus plus something which produces a dot o file and then it is followed by another c plus plus command which links libraries which are pre compiled versions of these classes along with your compiled version. So that is the facility that is available invariably in developing large programs that is what you would be doing using this now we will revisit the notion of classes because classes are nothing but an implementation of what you may call abstract data types and their manipulations using functions which are written specifically for that the notion of a class makes it a much better abstraction than an ordinary abstraction that we have used for data structures such as struct you remember struct we had defined struct and then we could use an array of struct if we wanted. So struct became some kind of an abstract data type for us it is not a full-fledged abstract data type an abstract data type should have facilities for manipulation similar to the normal data type in this context we had seen some class examples today we will look at the example of rational numbers as I said rational numbers are of the form a by b where a is an integer b is also an integer. So I have a pair of numbers this pair describes a rational number if I want to do a upon b plus c upon d then I know that this is equal to a d plus b c divided by b d. So I know how to operate upon rational numbers what are the operations that I can conduct on rational numbers add subtract multiply divide what is the advantage of retaining the final results in the rational number form I avoid any loss of precision in my calculations due to that floating point limited. So I can actually conduct all my computations in rational numbers and ultimately the final result I can convert into a floating that is one way of looking at it how do I implement rational numbers well I can write a program where I can write a struct where I say int a int b and I can define variables of the type struct and every time refer to this part and this part and implement everything here but then the implementation of the rational number and operations on the rational numbers will be visible to anybody who reads my main program and somebody wants to change the main program for something else that person might by mistake change some fundamental aspects which implement the rational number operation which is detrimental because I would have tested all those operations addition subtraction multiplication. So what I would like to do I would like to create a structure in which rational numbers are handled but to the end user I will say I have defined this structure I have defined functions for adding subtracting multiplying just use them this is where the class notion helps us enormous. Let us look at one particular implementation I have written a main program and a function first let us see the main program this is the main program this main program as assumes that there is a class of rational numbers defined somewhere and it attempts to use that class and its behavior in this class I am saying rational C 1 what it means that an object C 1 of the rational type should be created then I am defining another object C 2 but I in bracket I have said 3 comma 4 what it should mean generally you can guess I am defining another object of rational whose value is 3 by 4 third object 1 by 3 then I am using a function display C 1 I expect that the display C 1 should be able to display the numerator part and the denominator part this function is not part of the standard class which somebody has written for me the rational class so I will be writing this function myself I have another function here which says R add R add should stand for rational add I am going to pass two parameters to it one is an object C 2 another is an object C 3 and this R add function is actually a member function of the rational class itself so the fourth object C 4 I have written here C 4 dot R add C 4 dot R add C 2 comma C 3 I expect C 2 and C 3 are added in the rational number arithmetic sense and the result should become now my C 4 so the C 4 component should be appropriately changed based on this idea this is how I have written the program as I said we will look at the display function that I have written so this function says white display rational C it will expect object of the type rational here the implementation is given here it says to display rational number in two forms in A by B form has also as a floating point value so I have declared here float x into A comma B now I say C dot R components A comma B what does it mean C dot R components means components of the rational when I say C dot R components it must be a member function of the C and when I say A comma B I expect the A comma B components of this to become available to me now I can say x is equal to float A by float B and I can print the number as A and B and equivalent floating number as this in this particular case I am doing an important mistake why is that is mistake and why it is important I am assuming that the private data members of a class are accessible to me usually you would like to hide everything that is private to an object so this is not a good implementation I have I will be including on the Moodle this small program as well as my initial version of the implementation of class rational and I will indicate by notes what is wrong with this implement one of these things that I mentioned that the way I have written it I would of course have R components as one member function I would have the constructors of different types and I would have R add as another member function then I will mention why this implementation is not a good implementation what should be a good implementation the good implementation should do variety of things for example instead of having a function called add two objects multiply two objects suppose I have a class this time I will change the class I will call it with capital R rational suppose I have these objects C1 C2 C3 and I have initialized let us say I have initialized C1 as 2, 3 and C2 as 3, 4 now I would like to say somewhere in my main program C3 is equal to C1 plus C2 do you agree because I am adding two rational numbers so I would like to use the plus symbol of C plus plus which implies addition of integers which implies addition of floating point I would like to say I want to add two rational numbers and the addition is in the same spirit that it does addition of integer or floating so I would like to say I would like to use the same symbol for division for what you call multiplication etcetera more importantly consider my input and output statements I have a statement C in by which I can input x, y, z I would also like to say C4 isn't it input a rational number I know that rational number has two parts if you tell me in what format I should give the rational number why should I have to read if I had a structure for example struck R and then read C in R dot A R dot B that is what I would be doing if I had defined a structure but if I have an object I would like to do this I would similarly like to do this that is the power of expression that is possible because C plus plus permits you not only to define your classes and object characteristics but it also permits you to define or rather redefine or extend the definition of normal operators which exist in C plus. So, the normal operator in C plus plus which is the plus symbol means addition you extend the meaning of it of course how it will not automatically extend when you define the object class for rational you will have to give statements saying this is the meaning of that extension such an extension is called overloading of operators. So, in this case the operator plus is overloaded you can overload minus slash star etcetera you can also overload greater greater and less less symbols you may not be aware but these symbols are actually operators in C plus plus the greater greater symbol is called extract operator it extracts from an input stream of characters and converts it into a proper value like integer and flow this operator is called an insert operator it inserts the converted text into an output stream and these operators are defined in the context of streams of data one is input stream the other is output stream. These are called I stream and O stream of which C in and C out are merely some special manifestation we shall be studying these later in the class but today we will understand that this is possible what we will do is we will very quickly glance through the definition of the class we will be discussing the class rational in greater details on Friday and this class has been described completely in we will not spend too much time I want to spend just 5 minutes but I would like to advise you the following please read chapter 8 of Coohoon before you come to the next lecture on Friday because that chapter 8 describes the complete detailed description of the rational class starting with the rational for defining such a class it starts with the definition of member data elements member functions and it introduces a few new terms which we will discuss on Friday. So if you have studied chapter 8 before coming to the class you will be able to understand things more rapidly here we are just looking at it some comments I have added these are not there in Coohoon's book. So this is a class to handle rational numbers objects are of the type a by b. Now I have defining private data members int n value and int d value it is easy to understand numerator and denominator. Now I am defining member functions look at the constructors rational, rational int comma int it means I can give a default constructor and I can give a constructor with 2 parameters they have to be implemented here the implementation of rational bracket open bracket close could give some default value the best default value for the rational is 0 by 1 it is almost like setting something to 0 initializing integers or float to 0 is natural initializing a rational to 0 is also natural but 0 by something you have to say denominator cannot be 0 you set it to 1. In case I set it to int comma int then the first int is numerator second int is denominator that is employed. Now there are mutators and inspectors a mutator is a function which sets the value for private data member and an inspector is a function which inspects the value of a data member and gives you set value set n value set d value natural numerator value denominator int gate value int gate n value int gate d value again natural whatever object it is operating upon it will take the numerator and return it as int take this and return it as int here I have shown them as public member function in actual implementations they are not public member function they are functions called protected function a protected public member function can be used by you in your main program but a protected function cannot be used by you that means in your main program you can never write set n value set d value say gate n value gate d value you cannot never write what is the objective of such protection the object is now being completely protected from the internal data members you can never access direct never that is a that is a encapsulation and hiding principle which goes very strongly to write clean software now you would still like to know what are the value but are you interested in the components you are interested in the operations on those rational you are interested in ensuring that initialized rational value exist and operations can exist that can be done using protected functions because protected functions can be used by other member functions of the class but you cannot use them here is a r add function which I have written it has two rational things now I have these constructors notice that the constructors are using set n value set d value etcetera we will discuss these things in details I have just given you a glimpse of how the rational class is being defined and we will discuss the details of the implementation on the Friday lecture thank you.