C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file...

124
C++ Notes 1 By V. D. Gokhale ASTROMEDICOMP C++ PROGRAMMING BASICS Difference between C and C++ :- (1) When we invoke turbo C++ editor by c:\tc\tc [Enter]. The editor window shows the file name with .c extension. [noname00.c]. Means turbo C++ initially assumes that we that tc editor to write program in C. To tell the compiler, that we want to make program in C++, we should change the file extension to .CPP. ¾ This extension is the only that turbo C++ knows whether to use C or C++ compiler. ¾ The changing of extension from C to CPP , can be done by… Ö From file menu, use save as …. Option. Click the mouse or press ENTER key here. Ö A typing window will appear. Ö Type the desired file name, then type . and finally type CPP. Ö Then click on OK or press ENTER. Ö The default name of file on top of editor window will get changed to your desired file name with CPP extension. (2) In “C” for input (by scanf()) and for output (by printf()) the inclusion of file stdio.h” was not always necessary. Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include <iostream.h> on the top of the every program) (3) In “C” we use to write the main function as main(), but in C++, as a procedure, it is better to write void main(). The word void indicates that the main function is not going to return any value. ISO change int main() [empty bracket]. Thus the last statement should be “return(0);”. Note :- If no return value is specified , the default is int. Default parameters are int and char *[] which are command line arguments. (4) The C++ compiler ignores white space almost completely. (5) Output -> In “C”, the output is mainly accomplished by printf() function. In “C++” the output is a accomplished by “cout <<”. Where cout is an identifier, which is actually an object and << is known as “insertion operator or put to operator”. The desired output message should be enclosed in double quotes and the whole statement is then finally terminated by semicolon. e.g. cout << “message”; The output of this statement will the word -> message.

Transcript of C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file...

Page 1: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 1 By V. D. Gokhale

ASTROMEDICOMP

C++ PROGRAMMING BASICS ♣ Difference between C and C++ :- (1) When we invoke turbo C++ editor by c:\tc\tc [Enter]. The editor window shows the file name with .c extension. [noname00.c]. Means turbo C++ initially assumes that we that tc editor to write program in C. To tell the compiler, that we want to make program in C++, we should change the file extension to .CPP.

This extension is the only that turbo C++ knows whether to use C or C++ compiler.

The changing of extension from C to CPP , can be done by… From file menu, use save as …. Option. Click the mouse or press ENTER

key here. A typing window will appear. Type the desired file name, then type . and finally type CPP. Then click on OK or press ENTER. The default name of file on top of editor window will get changed to

your desired file name with CPP extension. (2) In “C” for input (by scanf()) and for output (by printf()) the inclusion of file “stdio.h” was not always necessary. Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include <iostream.h> on the top of the every program) (3) In “C” we use to write the main function as main(), but in C++, as a procedure, it is better to write void main(). The word void indicates that the main function is not going to return any value. ISO change int main() [empty bracket]. Thus the last statement should be “return(0);”. Note :-

• If no return value is specified , the default is int. • Default parameters are int and char *[] which are command line arguments.

(4) The C++ compiler ignores white space almost completely. (5) Output -> In “C”, the output is mainly accomplished by printf() function. In “C++” the output is a accomplished by “cout <<”. Where cout is an identifier, which is actually an object and << is known as “insertion operator or put to operator”. The desired output message should be enclosed in double quotes and the whole statement is then finally terminated by semicolon. e.g. cout << “message”; The output of this statement will the word -> message.

Page 2: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 2 By V. D. Gokhale

ASTROMEDICOMP

Here the desired output is enclosed in double quotes and the whole statement is finally terminated by semicolon. * We mainly use outputs by 3 ways. (1) Only text output. (2) Only variable output. (3) Text variable output. (i) Only text output :- In this we want only some text to get output (printed) on the screen. In such type the text should be enclosed in double quotes.

e.g. -> Suppose we want to get printed the text message ‘Every age has a language of its own’ on screen then… cout << “Every age has a language of its own”;

(ii) Only variable value output :- Some times we need to print variable value on screen. In this case just use variable name with cout << . without any double quotes.

e.g. -> int var1 = 10; int var2 = 20; int var3; var3 = var1 + var2; cout << var3; The screen will give output as 30. Here we want to print value in var3, hence we just use variable name without any double quotes. Note :- One of the most important difference in output by “C” and “C++” is …. In “C” while using printf() function, for getting variable values, we have to use identifier like %c, %f, %d for character, float and integer variable respectively. But in C++, there is no need of mentioning respective variable type. The cout << operator itself can judge the variable type. Means if we pass string to cout <<, it will print string, if we pass integer variable, it will print value of integer and so on. Thus happen due to t he property of “operator overloading” which is a feature of C++.

{ ISO changes in #include -> no .h is written. e.g. #include <iostream> ISO -> In “C” UDF [User defined functions] can call main(). But in C++ now it is illegal. No UDF can call main(). ISO changes in cout << it is considered as std :: cout << -> here std :: is a namespace. For multiple output, we can use single “cout” statement and then cascade

the “<<” operator as …. cout << num1 << num2 << num3;

Page 3: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 3 By V. D. Gokhale

ASTROMEDICOMP

} (iii) Both text and variable value output -> It is the combination of (1) and (2). Means text should be enclosed in double quotes and variable name without double quotes.

e.g. see example in 2 cout << “The sum is”; cout << var3; The output of above 2 cout statements will be “The sum is 30”.

• Here we get output in one line using 2 cout on 2 different lines. If we need to use only one cout to give both outputs we should cascade << operators twice. e.g. The same above example….

cout << “The sum is” << var3”; • Also suppose there is 1 cout statement, prior to another cout statement and

both of them do not have “newline escape sequence”, then the 2 outputs will appear on same line. To introduce newline… (1) Either use \n escape sequence within double quotes text. (2) Or use “\n” (with single quote) escape sequence any where in the cout

statement, but with << operator. (3) Or use a manipulator known as endl with << operator in cout statement.

But note that while using endl you must include iomanip.h header file with #include directive at the top of the program, above or below

# include <iostream.h>. [ endl is the new identification of ‘\n’]. (6) Comment -> As we know well, comments make the program readable to the programmer in future. We required comments to use in 2 situations.

• At the beginning of any statement of program. • At the end of any statement of program. (i) For using comments at the beginning of the line we can use // double

slash symbol, if the comment is short. This comment sign is readable in C++ only. But if the comment itself is quite bigger and if requires 2 or 3 lines, then instead of using ‘//’ 3 times, we can use “C” comment sign, as

/*……………………. comment .…………………… .……………………*/

(ii) But when we require statement at the end of a program segment, then use // commonly in C++.

(7) Variable definition -> In “C” we have to declare all variables before the 1st executable statement of a program. But in “C++” we can declare variable anywhere in the program, when we

Page 4: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 4 By V. D. Gokhale

ASTROMEDICOMP

want to use it. (8) Input -> In “C”, input from keyboard is mainly accomplished by scanf() function. In “C++” the input is accomplished by “cin >>”. When cin is an identifier and >> is known as “extraction operator or get from operator”.

e.g. int num;

cout << “Enter a 3 digit number : “; cin >> num; Here the message in cout will get displayed on the screen and compiler will wait for you to enter any 3 digit number. Thus cin >> allows compiler to wait for input. [ Note like scanf() , there is no need to pass data type and “&” prefix to variable format string to cin. ] Here we need to enter multiple values the there is no need of using “cin” every time. We can do it by cin >> num1 >> num2 >> num3; ISO -> std :: cin.

(9) In “C” multi time usable constants like PI etc, are predefined by # define preprocessor directive. This # define preprocessor directive can be used in C++ too but it is not so popular in C++. Instead of that in C++, const qualifier is used. Const qualifier specifies that the value of variable supplied by the word const, is not going to change through the program. Any attempt to change it, will result in an error. e.g. const float PI = 3.14159; The variable declared as “const“ can be used as size of array. e.g. const int size = 10; char arr[size]; The syntax of const qualifier is ….

1st the keyword const. Data type. Desired variable name, generally in block letters to let to know that it is

constant. Value to assign it with equal sign.

* const <data type> <variable name> = <assign value> By default “const” is an integer. e.g. const x; means int x;

(10) Manipulators -> Manipulators are operators to use with << insertion operator in const statement to modify the way of data displaying. The most common 2 manipulators are endl and setw();

• endl [ std :: endl ] :- Means “end line”. When this is used with cout the output gets displaye on next line at the beginning. Thus it is nothing but the “\n” newline operator expressed in terms of words.

Page 5: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 5 By V. D. Gokhale

ASTROMEDICOMP

endl flushes output stream while “\n” does not. • setw() [ std :: setw() ] :- Means “set width”. This manipulator is used for

formatted output, exactly one below the other, by setting width. For this we have to pass the desired width to it in brackets, such as setw(8) -> now it will set width of output for 8 columns. For using setw() manipulators , inclusion of iomanip.h header file is must. This is done by introducing line…. # include <iomanip.h> at the top of the program. (In ISO manipulators are added in namespace <iostream> which if included , no need of iomanip.h) There are yet other 3 manipulators std :: dec , std :: oct , and std :: hex which gives decimal , octal , hexadecimal value of the variable. They should used before the variable each time. e.g. int num 123; std :: cout << std :: dec << num << std :: oct << num << std :: hex << num << std :: endl; output :- 123 173 76 decimal octal hexadecimal ISO -> During automatic type conversion “C” changes value from higher data type to lower without any type of warning. But C++ now sets warning message of possible data loss. Basic streams -> cout (standard output) , cin (standard input), and cerr(standard error). Use them with std :: e.g. cerr << ….. [syntax is same as cout <<] Output goes to standard error device.

(11) Typecast -> In “C”, when we do typecast we enclosed the desired data type in brackets and keep the variable name open. e.g. If we want to change int x to float value we do ….(float) x; But in “C++”, the approach is easier and like function notation. Means data type is kept free, while variable name is enclosed in brackets. e.g. float(x); (12) In loops :- The loop is limited by braces. In C++ we can declare a variable inside this loop bode. Surprisingly variable declared inside the body or block is not visible outside the loop. e.g. int i; for(i=0;i<11;i++) { int sq; sq = i * i; cout << sq << “\n”;

Page 6: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 6 By V. D. Gokhale

ASTROMEDICOMP

}

• Here we declared variable “sq” inside the for loop block. This loop will give square values of number to 10.

But after ending the loop , if we again type cout << sq; Then compiler will give error, that the variable “sq” is not defined. This shown that variable declaration can be done inside the loop block and it will be visible only inside the block and not visible outside the block. This property is not in “C”.

(13) As per the point (7) we can define and declare variable anywhere in the C++ program , where we want to use that variable. This property can be used in loops too. e.g. for(int i=0; i<11; ++i) is valid. Means we define and declare variable I, inside the for statement. (14) Structures :- Structures should be studied in detail in C++, because they resemble to the key feature of C++ , i.e. “CLASSES”.

• The syntax of a structure is almost identical to the syntax of a class. • A structure is used for used for collection of data while a class is used for

collection of data and function. [ Though we say that structure holds data and classes hold both data and function , actually structure itself can also hold both data and function too. ]

• Declaration of structure in “C” and “C++” is same. But in “C” when we declare a structure variable of a particular structure , then we have to use the key word struct of the beginning , then the structure name and finally the variable name.

e.g. Suppose we define structure as ….. struct part struct { { int modelnumber; or int modelnumber;

int partnumber; int partnumber; float cost; float cost;

} }part; And now suppose we want to declare a structure variable part1 of struct part type, then in “C” the declaration is …. struct part part1; While in “C++” the keyword struct is not necessary. We can declare part1 structure variable of struct part type as …. part part1;

Page 7: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 7 By V. D. Gokhale

ASTROMEDICOMP

(15) Enumerated data types -> Same like structure , in “C” while declaring an enumerated data type variable, the word enum is must , while in “C++” the word enum is not necessary. e.g. Suppose we want to create an enumerated data type as “days” which is as follows :- enum days {sun , mon , tue , wed , thu , fri , sat}; and now we want to declare enumerated variables d1 and d2 of enum days type , then ……

• In “C” the declaration should be -> enum days d1 , d2; • But in “C++” the declaration is -> days d1 , d2; [ The word enum is not

necessary ]. • But there is a serious problem with enum in C++. That , C++ can not work it

out in input / output. e.g. enum direction {north , south , east , west}; direction d1; -> declaration of d1 variable of enum direction. d1 = south; -> Assigning value of south to it. cout << d1; -> Here we expect output as south. But the output arrives as 1 , as north = 0and south = 1. Means though we assign the name south to d1, we will get the output of its integer value and not the actual name.

• Boolean variables are those which give truth / false conditions. In C and C++ there is no such Boolean variable of builded data type. Mainly used to test the output of logical expressions.

By using enumerated data type and also by using the fact that falsity = 0 and truth = 1 , we can create a Boolean variable as …. enum Boolean {false,true}; -> Here we write false first because internally the

first name is assigned to 0. boolean b1; [ bool b = true ] [ Now bool is a data type. Hence there is no need of enum. You can directly say bool b = true; (0 = false and 1 or nonzero = true)] (16) Functions -> It is a unit of program , in which “repetitively used program statements” are grouped. This unit can be used any where in the program for multiple times.

• There are 2 reasons for which functions are used (i) Dividing a program into functions is one of the major principle of

structured programming. Thus functions provide “Conceptual organization of a program.” (ii) Any sequence of statements , that appears more than once in a program can be grouped as a function. Thus repetition gets avoided and program size is reduced. • Any function has 3 parts…

Page 8: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 8 By V. D. Gokhale

ASTROMEDICOMP

[ i ] Function declaration. [ ii ] Calls to the function and [ iii ] Function definition. [ i ] Function declaration :- Both in C and C++ , we can not use a variable, without telling the compiler what it is. Similarly we also can not use function in the program without telling the compiler. To tell the compiler , function must be declared at the beginning of the program. When a function is declared , then this declaration tells the compiler that “A function that looks like this is coming up later in the program.” This declaration is called as prototype.

* Syntax of function declaration -> <return data type> space <user defined name> space <pair of round brackets with list of function parameters data types separated by commas>; e.g. int vijay(double , double); This example indicates that ……

Function is going to return integer type value. The user defined function name is “vijay”. This function has 2 parameters (arguments) which are of double data

types , separated by comma and enclosed in pair of round brackets. The declaration is terminated by semicolon.

• When a function does not return any value, then the word “void” should be used in declaration. e.g. void vijay(double , double);

This example indicates that the function “vijay” is returning “no value” and hence the word “void” is used.

• When a function does not have any arguments (parameters) then in the pair of brackets , the word “void” is used. e.g. int vijay(void); [ By ISO , the function which has no parameters then its parenthesis may be empty ] In this example the function “vijay” is returning an integer value, but has no parameters hence the word “void” is enclosed in pair of round brackets. Or int vijay() -> legal by ISO.

• The function declaration can be done at 3 places in the beginning of program (i) When a function is used only by “main()” and not by any other sub

functions, then the respective function should be declared after “main()” but before the 1st program statement.

(ii) When a function is used by many sub functions of a program (including or excluding main()) , then this respective function should be declared before main().

Page 9: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 9 By V. D. Gokhale

ASTROMEDICOMP

The declaration of 1st type (after “main”) is known as local function declaration, while…..

The declaration of 2nd type (before “main”) is known as global function declaration….

(iii) Sometimes a function is used only by one another function and not by main(). Then this respective function can be declared locally in the function which will use it , after the definition of function.

Function declaration is also known as function prototype. Calls to the function -> Once declared , the function can be used anywhere and for many times in the function or program, just by maintaining its name. This is known as making “call to function”.

• If a function is declared globally , then it can be called by main() and any other sub functions.

• But if a function is declared locally, then it can be called by only that function, in which it is declared. If it is called by some other function then it causes error.

• The function which is initiated, is called as “called function”, while the function in which the “called function” is used, is called as “Calling function”.

• When a function returns any value , then it is assigned to respective variable by “=” operator. e.g. Suppose function “vijay” is returning an integer value and if is declared as “int vijay”, then if we want to assign the returned value to any integer variable like “num” , then we can call “vijay” as int num; num = vijay (Parameter list); Here the returned value by “vijay” function, will be assigned to integer variable “num”.

• If a function is not returning any value , means , if it is “void” , then just mentions its name and brackets with parameter list. But if it has no parameters , then keep brackets empty.

• Note that -> If the called function has parameters , then they must be of same data types as in declaration and should appear in same order as the declaration. e.g. -> suppose a function is declared as int vijay(int , double); and we want to call it in main()…. main() { int num1 , num; double num2; num = vijay(num1 , num2); ( This is a correct call )

Page 10: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 10 By V. D. Gokhale

ASTROMEDICOMP

o Because 1st parameter is “int” and 2nd is “double” in decleration.

o If call it like vijay(num2 , num1); then it will give wrong answer. Because “num2” is double and num1 is “int”, and this is contrasting with the declaration.

}

The function Definition -> To define a function is to write the code of the function. Function definition should be done at the end of program, after the closing brace. Function definition has 5 parts. (i) Function decelerator. (ii) Opening brace of the function. (iii) Function body. (iv) return statement. (v) Closing brace of the function.

(i) The line which is used while declaring the function, should be repeated here, with 2 changes…. • The parameters are written with their data types and

respective variable names, as user’s wish. Means if the function is declared as int vijay(double , int); then the definition’s 1st line should be …. int vijay(double a , int b) -> No semicolon. Here variables are used a and b. These variables are then used in function body.

• Note that, the decelerator of function definition should not be terminated by semicolon.

(ii) Then give opening brace. (iii) Then write the program statements, which we are going to use. (iv) “return()” statement should be used, if our function is returning

any value. The brackets after the keyword “return” should contain either variable name or the actual value.

(v) Closing brace. Note that :- Function decelerator must match the prototype exactly with respect to data type of return value and parameters and no. of parameters.

• When we use library functions like getch() , printf() , scanf() etc , then there is no need of writing their declarations or definitions,, because they are already

Page 11: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 11 By V. D. Gokhale

ASTROMEDICOMP

written in “header” or “library” files which should be included at the most beginning of our program by #include <> directive.

• Previously we stated that , before using a function, it must be declared 1st. But we can eliminate the function declaration, if the function definition appears in the program , before the 1st call to the function. This approach is better in smaller programs, but in large program declaration and definition approach is much better.

♣ Passing Arguments [ Parameters ] To Functions :- (1) Passing by value :- We can pass values either directly or using “value containing variables”.

(i) Passing values directly -> # include <iostream.h> void main() { void display(char , int); -> Declaration [ with semicolon ] display(‘*’,89); -> Call by passing values directly. } void display(char ch , int nm) -> decelerator [ No Semicolon ] { // function body starts int i; for(i=0;i<nm; ++I)

{ cout << ch;

} // function body ends }

• No return statement as function is “void”. • While calling the function display(), we directly pass values.

(ii) Passing variables -> Same above example can be written by passing variables. Just we have to assign “*” and 89 to variables and pass these variables to display. # include <iostream.h> void main() { void display(char , int); declaration. char star;

Page 12: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 12 By V. D. Gokhale

ASTROMEDICOMP

int num; star = ‘*’; num = 89; display(star , num); -> call to function by passing variables } The function display() is same as before. Here we are passing “*” and 89 to display(), but not directly, we 1st assign “*” to variable star and 89 to variable num and then we pass star and num to display() function.

Passing structure to function -> As like all variables we also can pass a structure variable to function. But as the desired structure is going to be used by both main() and function, it should be visible to function. And for this purpose just declare the desired structure globally [ before main ] and then use structure variables as the like our ordinary variables to pass to any function.

(2) Passing by reference :- In the way (1) we saw that arguments [ parameters ] are passed by their values [ either directly or embedded in variables ]. But , there is another way , that we can pass parameters to desired functions not using their values but using their reference.

• Purpose -> Passing arguments by “value” makes no changes in original values of variables. Means in previous example we assign ‘*’ to star variable and 89 to num variable. We pass them to display() function. The function display() copies these values into ch and nm variables respectively and use them in the function. But note that , no change is made to star and num , though changes can be made to ch and num.

Though above way is safest , sometimes we may need to deal with original variables (“star” and “num” in above example ). In such cases , when by using a function we want to change the original values, we should use “pass by reference” method. There is another advantage of using “pass by reference” method, is that , by “pass by value” method we can return only one value at a time from that function. But by using “pass by reference” method, we can force the function to return multiple values at a time.

• Method -> To indicate the compiler that, we are using “reference” method ,. ampersand (&) sign is used.

Changes are to be made in “declaration” and “declarator” only not in “call”.

In declaration the data type which you want to pass by reference should be immediately terminated by “&” sign.

Page 13: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 13 By V. D. Gokhale

ASTROMEDICOMP

E.g. int vijay(double , float , char); -> “value” method. Suppose you want to pass float data type by reference , then…. int vijay(double , float& , char); -> “Reference” method. Here the desired data type is immediately followed by “&” sign.

While writing declarator in function definition we write data type and

desired variable name too. Just terminated the data type by “&” sign. The declarator of above example will be …. int vijay(double n1 , float& n2 , char ch) { funtion body; return(variable name);

} float& n2 :- Here too , the data type is immediately followed by “&” then a space and then the variable name is written.

Note -> In “C” we use “&” as “Address off” operator and at the beginning of the variable , so as to indicate the “address of that variable in the computer’s memory”. But in “C++” the ampersand is used after the “data type” [ as like in “C” , it has no connection with variable name ] to indicate the “reference” and not the address. These 2 methods “Passing by value” and “passing by reference” can be

well explained with an example. Suppose you call a painter to paint your house. Then “to tell the painter about the wall, the paint, the color” is “passing by value”, while “painter comes in the house and does all things as it is without your intimation” is “passing by reference”.

• Passing structure by reference is same as other variables -> (1) Declare structure globally. (2) In function declaration write structure name in the

arguments list and immediate to that name write “&”. (3) Make usual call to the function , passing structure variable

name as usual. (4) In function definition, while writing function declarator,

write structure name, then “&” , then space and then the desired structure variable name, which you are going to use in the function body.

Page 14: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 14 By V. D. Gokhale

ASTROMEDICOMP

Note -> In “C” reference do not exist. In “C” the same purpose is saved by “pointers”. But in “C++” there are reference as well as pointers too.

♣ Returning from function :- (A) Returning values from functions :- We write any function to get some answer. This answer is usually returned from that particular function.

• The return statement -> When we want to return an answer from the function , 2 cases can take place…

Either the answer variable is already declared globally, then there is no need of mentioning the name of that answer variable along with return statement. In the program , after function call just write the answer variable name either in “cout” or in “equation”, you will get proper change in that variable , done by the function.

Or the answer variable is declared locally, in the function , and we want to return this answer to the main program , then this answer variable is written in front of return statement by 2 ways.

(i) return <answer variable name>; e.g. return kg; (ii) return (<answer variable name>); e.g. return(kg);

Use of brackets is optional. Note :- (1) When a function returns some answer then the return data type must be indicated in function declaration and in function declarator. (2) If function does not return any value then there is no need of “return” statement. But such functions must be indicated by “void” term both in declaration and in declarator. (3) If function is not returning any value and if “void” is not

mentioned , then compiler will consider this function as “integer” returning function by default. And if in such cases “return” statement is not used at the end of function, the compiler will give warning “Function should return a value”. So either write “void” to non value returning function or write return; at the end of such function. (4) If function is small , means it contains only one statement or equation , then to avoid unnecessary variable declaration , we can say write that single statement or equation in front of “return” statement directly. e.g. Using variables Avoiding unnecessary variables float poundtokg(float pnd) float poundtotkg(float pnd) { {

Page 15: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 15 By V. D. Gokhale

ASTROMEDICOMP

float val , kg; return 0.453592 * pnd; val = 0.453592; }

kg = val * pnd; Here unnecessary use of val , kg return kg; is avoided by mentioning

} equation along with return statement directly.

Note ->

• return statement can appear anywhere in the function body but better is to use it as last statement if not unavoidable;

• Ignoring return value :- If suppose your function return a double type value, and in calling function you do not specify a catcher variable to hold that return value, then function runs smoothly without any problem. But this is an occasional circumstance.

• Returning structure variable :- As we can return all data type variable, we also can return structure variable too.

We do function declaration , starting by the name at return data type as “int vijay(double , double);”. Here we will use function “vijay” to return “int” value. Similarly, when we want to return structure variable from a function, we have to write structure name at the beginning of function declaration and function declarator. As we know that this structure is going to used by main program and function, the function should know it, and hence we should declare the structure globally. While using return statement , then just mention the name of structure variable you want to return from that function. But in the function body structure element must be operated separately and use structure variable name with return statement. Don’t use equation structure variable with return statement.

(B) Returning by “reference” from functions -> In procedural programming returning a value not by value itself, but by reference , is not much needed. But in “overloaded operator” part it is must. The major advantage of returning by reference is that we have mention function calls in our program to the right side of equal operator and not to the left side. But after returning by reference we can use function names on the left side of equal operator too. Method of returning by reference ->

(1) In the function declaration , after the return data type, immediately write “&” the reference operator. Then space and then the function name etc.

Page 16: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 16 By V. D. Gokhale

ASTROMEDICOMP

(2) In function definition, while writing function declarator do the same thing. Means after return data type, immediately mention “&” and then proceed as usual.

By doing this, the desired function will return the reference of respective data type to your main function. But , while doing this the variable , reference of which you want to use both in main program and in function , must be declared globally and also the function should be declared globally. e.g. # include <iostream.h> int x; Global declaration of both the variable int & setx(); reference of which we want to use and void main() the function as well. { setx() = 92; -> Function can be used on left side of equal operator.

cout << “x = \n” << x; } int & setx() {

return x; }

Here setx() = 92 statement assign value 92 to the variable returned by this function. Now setx() returns integer value of x variable , thus 92 gets assigned to this x and returned to main program which gives output. x = 92. ♣ Overloaded functions :-

• An overloaded function is that function which appears to perform different activities depending on the kind of data sent to it. e.g. # include <iostream.h> void repchar(); Same function name with different arguments void repchar(char); and different function bodies codes. void repchar(char , int); int i;

Page 17: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 17 By V. D. Gokhale

ASTROMEDICOMP

void main() { repchar(); -> 1st call with no parameter. repchar(‘=’); -> 2nd call with 1 parameter. Repchar(‘+’ , 30); -> 3rd call with 2 parameters. } void repchar() { for(i=0;i<79;++i) No parameter is processed. cout << ‘*’; 1st code. cout << endl; Loops for 79 times and prints ‘*’ for 79 times. } void repchar(char ch) { for(i=0;i<=79;++i) Character parameter ‘=’ passed but not integer. cout << ch; 2nd code.

cout << endl; Loops for 79 times and prints ‘=’ sign for 79 times.

} void repchar(char ch , int n) { for(i=0;i<=n;++i) Here both character and integer parameters cout << ch; are passed. cout << endl; 3rd code. } Loops for 30 times and prints ‘+’ sign for

30 times. In above example same function name “repchar” is used and declared globally 3 times with different parameters. Function body codes for these 3 declarations are written 3 separate times.

1st code is written for ‘*’ character and for looping of 79 times in one single line. 2nd code is written with one parameter of character type and in “call” the

character ‘=’ is passed to it. Here too , loop counter is for 79 times in one single line. 3rd code is written with 2 parameters. One is character type and other is integer

type. Here in “call” the character ‘+’ is passed and the integer 30 is passed which is used as loop counter. This code gives output of the character ‘+’ for 30 times in one single line.

Page 18: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 18 By V. D. Gokhale

ASTROMEDICOMP

The surprising thing is that , same function name , with different parameters and with different function bodies give different outputs. How compiler knows ? the answer is though compiler see one function name , it differentiates the same name for 3 different times , because parameters are different for each time. This is knoes as function overloading.

To do this -> (1) Same function name should be used. (2) Declarations should be made globally and separately for

every time. (3) Function bodies should be written seperatly for every

different purpose. o Feature of overloading is not present in “C”.

• Different kinds of arguments ->

The compiler can also distinguish between overloaded functions with the same number of arguments , provided their type is different. Means suppose there is a function with one argument [parameter] which is a structure variable. Then as usual it will get operated on the passed structure variable. But if we pass one but different kind of variable, then too, the same function will work for float variable too, though the float variable is not structure variable. This overloading happens

• If the same function with same number of arguments but of different types declared 1st globally, and

• Their codes are written separately. e.g. -> # include <iostream.h> struct distance { int feet; float inches; };

void convert(distance); Same function , with same number of arguments void convert(float); (here one argument) but of different types [ one is void main() struct while other is float ] declared globally.

{ distance d1; float d2;

d1.feet = 5; d1.inches = 10.5; Structure variable is assigned values.

Page 19: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 19 By V. D. Gokhale

ASTROMEDICOMP

d2 = 76.5; Float variable is assigned value. convert(d1); -> 1st call with structure parameter. Convert(d2); -> 2nd call with float parameter. } void convert(distance d) { cout << d.feet << “-“ << d.inches << “\n”; } void convert(float d) { int f; float i; f = d / 12; i = d – f * 12; cout << f << “-“ << i << “\n”; } Here same function “convert” is used with one parameter. 1st time the parameter is a structure variable , but 2nd time instead of structure variable a float variable is passed. Note that same function with same numbered but different typed variable arguments are declared globally and separately. Also their function bodies are written separately too. • Default arguments :- Not only above 2 cases , but if we provide a function its

all default arguments , declare it globally and if you forget to give all parameters in its “call”, then by default arguments it will work with no problems.

Arguments :- left -> right -> Pascal calling convention. e.g. -> # include <iostream.h>

void repchar(char ch = ‘*’ , int n = 79); -> Here we declare function globally with global direction at its default parameters too.

void main() { repchar(); -> 1st call with no argument. repchar(‘=’); -> 2nd call with 1 argument. repchar(‘+’ , 30); -> 3rd call with both arguments. }

Page 20: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 20 By V. D. Gokhale

ASTROMEDICOMP

void repchar(char ch , int n) { int i; for(i=0;i<=n;++i)

cout << ch; cout << endl;

}

• Very Important Either omit all arguments or omit right sided arguments. Never omit

first left argument alone. Means repchar(79); will be illegal. This is because compiler looks for arguments left to right. Hence 1st parameter is left and it is either absent with all other parameters also absent or only it can be present.

If there are 3 arguments rule remains same, you can not omit 1st and 2nd. Means you can not omit an argument unless you omit argument to its right.

Here function “repchar” is declared globally with character parameter ‘*’ and

integer loop counter 79. These are function’s default parameter. While calling “repchar”, 1st call is made with no arguments, this call will give

output of ‘*’ for 79 times in one line. 2nd call is made with only one character parameter “=” , but no integer parameter is supplied. Though it is , it takes “=” sign in place of “*” and takes integer 79 as default and will give output of “=” signs for 79 times in one line. In 3rd call we provide both parameters. This time default parameters (* & 79) will not work and output will be of ‘+’ sign for 30 times in one line.

• Inline functions -> When we write a function and call it in our main program, compiler when see the call it exist from the main program, jumps to the function code, executes it, take necessary values and rejumps back to the main program. This takes negligible but some times in execution of program. If we still want to save this time and make the program execution faster, then we can use INLINE FUNCTION property. What to do ? Generally we declare function at the beginning of program and

write the actual function code at the end of closing brace of main program.

While converting this usual function into Inline function -> (1) 1st write the keyword “inline” and (2) Then write the function code as it is with declarator function body as it is

but globally means before main(). So that function should be seen by the compiler before the 1st call to it.

Page 21: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 21 By V. D. Gokhale

ASTROMEDICOMP

e.g. -> By ordinary way # include <iostream.h> void main() { double convert(double); -> Usual function declaration double ang;

ang = -155.0; ang = convert(ang); -> Usual function call cout << “angle = “ << ang << “\n”; }

double convert(double an) -> usual function definition with { declarator

while(an < 0.0) an = an + 360.0;

while(an >= 360.0) an = an – 360.0;

return(an); }

• This is just an example of inline function, actually looping structure like for, while , do ….. while are not allowed in inline functions.

By making INLINE FUNCTION :-

# include <iostream.h> inline double convert(double an) The function definition with declarator

{ is written globally , before main and with while(an < 0.0) keyword “inline”.

an = an + 360.0; while(an >= 360.0) an = an – 360.0;

return(an); }

void main() { double ang; ang = -155.0; ang = convert(ang);

Page 22: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 22 By V. D. Gokhale

ASTROMEDICOMP

cout << “Angle = “ << ang << “\n”; } Making a function INLINE :-

(1) Compiler does not jump to function code, but makes the function body as a part of program whenever call is made.

(2) There is no need of separate declaration at the beginning of program. (3) Speed of execution gets increased as there are no jumps. (4) But make those functions “inline” which are short means of one or two

lines.

CLASSES AND OBJECTS

o Read structures in “C” 1st and then proceed.

• In past “C++” was termed as “C with classes”. This nomenclature shows that “classes” are the key features of C++ classes are just like structures. Structures is used to group the data items together while class is used to group data and related functions together. Though this is the normal usage of structure , strictly speaking, structure also can be used to group data and function together.

But the key feature of C++ is data hiding. Means in a class we can make data as private, so that the respective data is accessible only by the class, in which it is declared. [ Data hiding is also know as Data Encapsulation] Hence in C++, data and function are “private” by default , while these are “public” in structure by default.

• Classes and objects :- Placing data and functions together into a single entity is the central idea of Object Oriented Programming [OOP], which gives birth to the idea of classes and objects.

Suppose we declare an integer variable num as … int num;

Then we can say that num is a variable which is supported to store any integer value only. Similarly when we declare a structure variable, we declare it with structure name and then desired variable name. e.g. struct vijay { int num; -> Structure definition (vijay).

Page 23: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 23 By V. D. Gokhale

ASTROMEDICOMP

float val; }; void main() {

vijay v1 , v2; -> Structure variable declaration (v1 , v2 of “vijay” type)

} On the same line class is defined and then its variable are declared. Variables of a class is known as objects. While defining a class, the differences with structure definition are

(1) Replace the word “struct” by the word “class”. (2) Make data items private. [ This is the “in general” rule. If desired you

can make the data “public”. But as encapsulation of data is the major feature of C++, generally all data items are made “private”. ]

(3) Make functions, “related with the data” as “public”. [ This is also a “in general” rule. If desired, you can make functions private too. ]

(4) Opening and closing braces, with termination by semicolon are similar as like structure declaration.

(5) Then, in main while declaring “class variable” [ Onwards we are going to call them as “objects”] i.e. objects 1st write the class name and then write the desired object name. If there are more than one object, then separate object names by semicolon and after declaration of objects semicolon should be given at the end of statement. [ Similar to structure variable declaration].

Thus, general syntax of class and object is :- class class-name -> 1st type the keyword “class” and then desired name of

the class. { -> Opening brace. Access specifier; -> Type the keyword “private” or “public” or”protected” ,

followed by colon; data; -> Type data items with their types and finally semicolon. Functions; -> Type function names with their return types and finally

by semicolon.

Page 24: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 24 By V. D. Gokhale

ASTROMEDICOMP

Access specifier; -> Data; -> So on. Functions; -> }Object List; -> Closing brace with either list of objects declare here

terminated semicolon or just give semicolon and declare object list in main().

or

void main() {

class name object list separated by commas; -> If you don’t declare object list at the closing brace of class, then declare it in main as…

1st give class name. Then give object name [ if more

than 1 object , then separate by commas ].

Finally semicolon. }

e.g. # include <iostream.h> class smallobj -> The keyword “class” followed by class name. { -> Opening braces. private : -> Access specifier.

int somedata; -> Data with its data type and semicolon termination.

public : -> Access specifier with colon termination. void setdata(int d) -> Function with its return type and parameter. { somedata = d; } -> Function body defined in the class. void showdata() -> Another function with its return type with no

{ cout << “Data is “ << arguments and its function body. somedata << “\n”; }

}; -> Closing brace. As no object are declared here , terminated by semicolon.

void main() -> main() function.

Page 25: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 25 By V. D. Gokhale

ASTROMEDICOMP

{ -> Opening brace of main function. smallobj s1 , s2; -> Objects of the class are declared. s1.setdata(1066); -> Function of the 1st object. s2.setdata(1776); -> Function of the 2nd object. s1.showdata(); -> Function of the 1st object. s2.showdata(); -> Function of the 2nd object. } -> Closing brace of main function. Now we will explain all features of “class and object” with this example :-

In this example the class is “smallobj” which is contain one data item and 2 functions. The data item declared within a class is known as member data. [ As the desired data is member of declared class ] Similarly function declared within a class is known as member function [ As the desired function is member of the declared class ].

An object has the same relationship to a class that a variable has to its data type. Means… int num; -> Here “num” is an integer variable type. smallobj s1; -> Here “s1” is t he object of class smallobj type. Thus an object is said to be an instance of a class.

In this example , smallobj class is declared before main(). Means classes should be defined globally.

Objects of smallobj class are not defined after its declaration. Hence just semicolon is given after the closing brace of smallobj class. If desired we can declare s1 and s2 of class smallobj as ….

class smallobj { class body as before. }s1 , s2; -> Declaration of objects at the closing brace of class, terminated by semicolon.

But , in this example objects s1 and s2 are declared in main with the class name , then object names and ( Separated by comma ) and finally a semicolon.

Keywords private and public -> As stated before the key feature of C++ and OOP is “data hiding”. Means the data within a class can not be accessed by other classes and functions. Such data is made accessible only to that class in which it is declared and thus only respective class member functions can access such data. Thus “data hiding” is done by the keyword “private” (followed by semicolon). Now until we use another access specifier like “public”, all items following the word

Page 26: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 26 By V. D. Gokhale

ASTROMEDICOMP

“private” will be private , to the class. [ In C++ , the keyword “private” is optional, means if this keyword is not used , the member items will be automatically considered as private by the compiler.]

When we want that, member data or functions of a class should be accessed by any other class of functions then to allow this use the keyword “public” (followed by semicolon). Then every data item or function , following the word public will be accessible to any other function in main program. [ To facilitate “Data Hiding or Data Encapsulation”, usually Data Items are made private and functions are made public ] There is another access specifier besides private and public and that specifier is “protected”, which we will see in Inheritance. Because this keyword is needed only there. As an unwritten rule, though data items are usually declared as private and functions as public , this is not hard and fast. Means if desired we can make data items public and function as private.

The data items declared inside the class [ whether private , public or protected ] is known as “Member data”. Here there is only one data item “some data” which holds integer variable type and declared as private hence accessible only by member functions of some class and not by others.

The function declared inside the class [ whether private , public , or protected ] is known as “Member function”. In this example setdata and showdata are the 2 member functions , whose function body is defined in the class itself.

Note -> Small functions should be declared in the class itself. [ Without the word “inline” such functions are considered as “inline” by default ] When the function is bigger , it can be declared elsewhere [ usually after main] .To do this… (1) 1st declare the function with its return type and parameter as

prototype declaration. (2) Then , after main or after the class

- 1st write return type of the function. - Then the class name, whose member this function is. - Then double colon [ :: ]. - Then function name and its parameter with variable as usual. - Then opening brace, function body and closing brace as usual. Here double colon [ :: ] is known as scope resolution operator.

Member functions defined outside the class.

Page 27: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 27 By V. D. Gokhale

ASTROMEDICOMP

e.g. :- The function “setdata” can be written by this way too…. # include <iostream.h> class smallobj { private : int somedata; public : void setdata(int); -> Prototype declaration void showdata() { cout << “Data is “ << somedata << “\n”; } }; void main() { as before. } void smallobj :: setdata(int d) Function of the class but declared { outside the class with return type somedata = d; class name :: function name } (parameters)

The most important point about functions in class , is the member data

items are directly accessible by member functions of respective class. Means … in both setdata and show data functions we can use somedata variable without any special declaration , though the functions are written inside or outside the class.

The member functions in t his example are written on the same line with braces. Bur if we want to write in usual methods with separate lines we can. This is just to save space.

Defining objects -> As stated before objects of a class can be declared at 2 places (1) Either at the closing braces of class (2) Or inside the main function.

Declaring objects at the closing brace of class , does not require special

Page 28: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 28 By V. D. Gokhale

ASTROMEDICOMP

notation of class. Just separate the objects (if more than 1 ) by commas and finally give semicolon. But declaring objects inside the main() requires 1st the class name and then objects names separated by commas and finally a semicolon. In this example objects s1 and s2 of class smallobj are defined by 2nd method. Note -> When we declare a class, it just tells compiler, what type of class will appear in future program. But it doesn’t create any space in memory. As soon as we declare objects, then memory for that objects gets created in the compiler. Means in above example special memory sets for both s1 and s2 are created separately.

Calling member functions of a class program -> Now when we need a function which is member of a class, e.g. setdata(), we can not call it is as usual like… void main() { setdata(1066); -> Wrong call , meaning less to compiler. } Because as we know member functions (like structure members) should be identified by their objects only. Thus if we want to call setdata() function, we should call it with in its objects like …. s1.setdata(1066); or s2.setdata(1776); Note -> As computer keeps separate memory for different objects, s1.setdata(1066) and s2.setdata(1776) are 2 separate different calls to the same function.

Thus when we call s1.showdata(), it will give output 1066 and when we will call s2.showdata(), it will give output 1776.

While calling member functions or member data items of an object of a class -> following syntax is used object name . member data or member function

Here “.” Operator is same as structure member operator called as period.

In above example , there is 1 member data item and 2 member functions. Similarly in a class, there may be as many data members and

Page 29: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 29 By V. D. Gokhale

ASTROMEDICOMP

functions as we can. Similarly in above example we define only 2 objects of a class , we can define as many objects as we wish. Not only that , we can define array of objects too. In this case the objects will be differentiated on the basis of their index numbers. e.g. smallobj s[5]; -> This declares 5 objects of smallobj class with s[0] , s[1] , s[2] , s[3] , and s[4] differentiation.

In this example we use integer type data item. Similarly we can use any type of data item like float , double , char , string , array , structures and unions enums , etc. On the same line , in this example both functions are void ( non returning ) , but we can use any type of user defined or library function such as returning any data type or using any data type as parameter. Not only this but we can use 1 class as a data member of some other class, we also can use object returning function or function with object as its parameter.

♣ Constructors :- Suppose we have a class, say smallobj and we have 2 items and 2 functions in it. Like …. class smallobj { int i , somedata; -> Here keyword “private” is not used , because by

default , if no access specifier is used , data is private.

public : void setdata(int d); { somedata = setdata(); } void showdata() { cout << “Data is “ << somedata << “\n”; } } Now suppose in main() we define s1 , s2 , s3 objects of smallobj class as …. smallobj s1 , s2 , s3;

Suppose further in program , we need such an operation in which the variable i ( or someone else) is set to 0, then everytime when we use any object s1 , we have to write i = 0; In main program , when we wish to use s2 or s3 object then too, for every time before using an object we should explicitly mention i =0; To avoid this repetitive declaration of I = 0, whenever object will be created , we can include this statement in a function and make that function as

Page 30: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 30 By V. D. Gokhale

ASTROMEDICOMP

our class member. So we create a function called void init() and include it in the class smallobj as …. class smallobj { as it is.

void init() Here the function is added in the class. { i = 0; }

as it is. }

Though we add this function in our smallobj class, when we want to use s1 object we have to 1st call this function as …. s1.init(); or when s2 object s2.init(); and so on. Thus problems remain same. Only the change is that instead of repetitive typing of I = 0, now we are repeatedly typing s1.init() or s2.init() and so on. Above explanation states that , we need such a function which will get initialized itself when it is created , without the special need to make a separate call to a member function … such a function is known as constructor. How to built a constructor function…

It should not have any return type. ( Not even void ) It must have same name as that of class. Usually it should be very small, having 1 or 2 lines at most. Usually those functions should be made constructors , which we want to

use many times in our program and which should get automatically initialized.

e.g. Increment or decrement counters. In the given example of last page , we can create constructor for i = 0 as .. class smallobj

Page 31: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 31 By V. D. Gokhale

ASTROMEDICOMP

{ int i, somedata; public : void setdata(int d); { somedata = d; } void showdata() { cout << “Data is “ << somedata >> “\n”; } smallobj() -> Constructor { i = 0; } Same name of the class and no return type. }; Using the same name for constructor , as that of class is the only way , that compiler knows, the desired function is of constructor type.

♣ Destructor :-Similar to constructor functions too. As constructor functions get automatically initialized as an object is 1st created , the destructor functions get automatically called when an object is destroyed, (means when we close use of an object of a class). The basic 2 rules of constructor syntax are same for destructor functions too, only the difference is that name of the destructor function ( i.e. same name as that of class ) should begin with tilde more i.e. ~. e.g. -> class foo { private : int data; public : foo(){ data = 0; } Constructor ~foo(){ } Destructor Begin with tilde with no parameters / arguments. };

• Destructor have no parameters i.e. no arguments. • Usually constructors and destructors appears in same class , when we allocate

or assign memory by constructors , then to de allocate that memory , destructors are used.

♠ Overloaded constructors :- Now we know that in C++ “Overloading” process, is to give “same names” to functions and pass different typed arguments.

Page 32: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 32 By V. D. Gokhale

ASTROMEDICOMP

Similar activity can be expected from constructor too. Suppose , we want a constructor to get initialized and variables in that function should get values , AND at the same time , we want constructor to get just initialized but with no values, then 2 constructors with same name and different parameters can be declared within a class. e.g. -> class distance { private : int feet; float inches; public : distance(){ } <- Constructor, same name as that of

class, with no parameters and no statements just 2 braces.

* When you want to create a parameterized constructor , 1st there should be a without parameter constructor with or without statement.

distance(int ft , float in) <- Constructor , same name as that { feet = ft; inches = in; } of class and as that of above function. With 2 parameters and 2 statements. void showdist() { cout << “Distance = “ << feet << “-“ << inches << “\n”; } };

Here using same name “distance” for 2 functions and 1st with no arguments and 2nd with 2 arguments we make “Overloading” of the function “distance”. And at the same time it is a constructor function , because it has same name as that of class. Thus this is “Overloaded Constructor”

• Above example also states that, though we can not pass parameters (arguments) to a destructor function,, we can pass parameters (arguments) to constructors.

• Constructors and destructors functions , as stated before , are small , hence their function bodies can be directly written in a class in compressed manner in a single line with white spaces.

Page 33: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 33 By V. D. Gokhale

ASTROMEDICOMP

But this is not a rule. If we wish , for more clarity we can define their function bodies outside the class before or after main() using :: operator as stated before.

• When the constructor is parameterized , means when the constructor has parameters , and those parameters are initialized in their function bodies, then while defining objects in main(), we can directly assign values to the objects.

• By the example on previous page…. There is no need of …. void main() { distance d; d.showlist(); } We can directly give values as …. void main() { distance d(25 , 10.6); -> This statement tells compiler , that d

is an object of class distance. }

• Similarly when a constructor function has only 1 parameter , then it becomes a special case, now we can directly initialize the object as soon as it is declared in our main program. e.g. -> class distance { private : int a; public : distance(int i) { a = i; } void showlist() { cout << “Distance = “ << a << “\n”; } }; void main() { distance d = 99; -> Direct initialization. d.showlist(); -> This will directly display 99. }

Page 34: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 34 By V. D. Gokhale

ASTROMEDICOMP

• When constructor and destructor are executed ?

As a general rule -> An object’s constructor is called when the object is declared and an object’s destructor is called when the object is destroyed. 1st of all we should consider 2 cases , either onjects are declared globally or objects are declared locally…

o A local object’s constructor functions are executed , when the object’s declaration statement gets executed by the compiler. When 2 or more objects (with constructor) occur in the same statement , then their constructor are called in the same order as their object occur, from left to right.

A local object’s destructor functions get executed in the reverse order of the constructor functions.

o A global objects’ destructor functions get executed in the reverse order of constructor functions and after termination main() program.

Following program will illustrate above facts

# include <iostream.h> class myclass { public : int who; -> No private data. myclass(int i) -> Constructor with parameter. { cout << “Initilizing” << i << “\n”; who = i; } ~myclass() -> Destructor. { cout << “Destructing” << who << “\n”; } }g1(1), g2(2); -> Global objects of myclass class. void main() { myclass l1(3); -> Local object of myclass class. cout << “*****” << “\n”; -> Some message. cout << “\n”; -> Plane line. myclass l2(4); -> Another local object of myclass

class. }

The output of above program is …. Initializing 1 -> This is due to global object g1. -> Left To Right. Initializing 2 -> This is due to global object g2 -> Left To Right. Initializing 3 -> This is due to local object l1.

Page 35: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 35 By V. D. Gokhale

ASTROMEDICOMP

***** -> This is due to “cout” after l1. Initializing 4 -> This is due to local object l2. [ Initializing Top to Bottom before and after main() as

global and local. ] Destructing 4 -> This is due to destruction of local l4.

Destructing 3 -> This is due to destruction of local l3. Destructing 2 -> This is due to destruction of global g2.

Destructing 1 -> This is due to destruction of global g1. [ Destruction from Bottom to Top after main(). ]

• This output shows that the last initialized object by constructor is the 1st to get destructed by the destructor. This shows that the local objects follow Last in First out mechanism. Means last objects are stored on stack.

♠ Objects as function arguments :- [ Passing objects to function] As like structures can be passed to a function as it’s parameter, whole object can be passed to a function. In that function we can use the passed object as a whole or its component too. This function may be a member function of same class or may be outsider function. e.g. -> # include <iostream.h> class distance { private : int feet; float inches; public : void getdist() { cout << “Enter Feet : “ << “\n”; cin >> feet; cout << “Enter Inches : “ << “\n”; cin << inches; }

void sumdist(distance , distance); -> This function should be declared outside the class. void showlist() { cout << “Distance = “ << feet << “-“ << inches << “\n”; }

};

void main() {

Page 36: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 36 By V. D. Gokhale

ASTROMEDICOMP

distance d1 , d2 , d3; d1.getdist(); d2.getdist(); d3.sumdist(d1 , d2); d3.showlist();

}

void distance :: sumlist(distance di , distance dj) { inches = di.inches + dj.inches; feet = 0; if(inches >= 12.0) { inches = inches – 12.0; feet = feet + 1; } feet = di.feet + dj.feet + feet; }

Suppose we want to create such a program which will add 2 distances in feet and inches and will give sum of those distances in feet and inches for this …

We create a class called distance. In this class we declared 2 private variables and three public member functions. Out of the 3 functions we declare and define 2 functions in the class body itself. While the 3rd function is defined outside the class using “::” scope resolution operator.

“feet” is an integer data and “inches” is an float data. The function getdist() will allow user to enter distance in feet and inches. The function showlist() will display the distance.

The 3rd function “sumlist()” is an important one. It is declared outside the class. Using scope resolution operator. In this function we passed to objects of distance type as arguments. Thus the prototype is defined in the class. In this function body we add inches from the parameter objects (di and dj). Now we know that 12 inches = 1 feet. Hence if the sum of the inches is equal or greater than 12 , then this 12 should be subtracted from the sum of inches and thus 1 should be added to feet. Now as data feet is private , it will not get initialized to 0. Thus we should 1st initialize feet to 0. Then by “if” statement feet is incremented, if sum of inches will exceed 12. then to get total “feet” we add previous feet (either 0 or incremented) and taken feet from 2 objects di and dj. Then we close the function.

Page 37: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 37 By V. D. Gokhale

ASTROMEDICOMP

Now in main(), we declare 3 objects of class distance as s1 , d2 , d3. d1 and d2 are 2 objects, which will be passed to sumdist() to add 2 object’s feet and inches respectively. Why d3 is necessary. ?

Because we want to display the sum of feet from d1 and d2 and sum of inches from d1 and d2, by showdist() function, if we use d1.showdist then it will print feet and inches of d1. Similarly if we use d2.showdist(), it will print feet and inches of d2. We don’t want this, but we want summation of feet from d1 , d2 and summation of inches from d1 , d2. Thus results ( of summation of feet d1 and d2 [ d1.feet + d2.feet ] and summation of inches d1 and d2 [ d1.inches + d2.inches ] ) should be stored in same other object say d3. hence declaration of another object is made d3.

Now we call d1.getdist() to get distance of d1 and d2.getdist() to get distance of d2. by saying d3.sumdist(d1,d2), we pass whole objects d1 ,

d2 to sumdist , which will give sum of distances from d1 and d2 and will store in feet and inches variables of d3. Thus now saying d3.showlist() we get the summed distance in feet and inches. By this program we can assure that objects can be passed to member functions as structures do.

♠ Returning objects from functions :- While returning structure from a function, we have to declare the function starting by its return type as the name of the structure. Similarly if we want to return an object from a function the prototype should be declared in the class starting the class name as its return type. Obviously when we write function body, in that we have to declare one temporary object of same class , do necessary operations and finally return that temporary object to our main program. We can change previous example slightly to do above things -> # include <iostream.h> class distance { as it is.

distance sumdist(distance , distance); -> Prototype declaration.

This function now return an object of distance class type.

Page 38: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 38 By V. D. Gokhale

ASTROMEDICOMP

as it is. };

void main() { distance d1 , d2 , d3; as it is. d3 = d3.sumdist(d1 , d2); -> An object d3 is assigned to the

function sumdist(). d3.showdist();

} distance distance :: sumdist(distance di , distance dj) { distance temp; -> As this function is going to return object, one

temporary object is created. temp.inches = di.inches + dj.inches; Necessary operations temp.feet = 0; are now done on the if(temp.inches >= 12.0) data items of temporary { object and finally this temp.inches = temp.inches – 12.0; temporary(temp) object temp.feet = temp.feet + 1; is returned. } temp.feet = temp.feet + di.feet + dj.feet; return(temp); -> The object temp is returned.

}

In this example and in previous example the function prototype of sumdist() is changed from void sumdist(distance , distance); to distance sumdist(distance , distance); By replacing the word “void” by “distance” , now this function becomes able to return an object of class distance type.

In main(), now d3 object is assigned to the “sumdist()” function. So that all object returned by this function will get assigned to d3 object.

Page 39: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 39 By V. D. Gokhale

ASTROMEDICOMP

While writing function body the word “distance” comes twice. Once , for the return type of function and secondly for the name of class. This has to be done because we define this function outside the class, hence scope resolution operator is used.

In the function body of “sumdist()” , as this is going to return an object of “distance class”, the returning object is declared as distance temp; then the operations are done on temp.inches and temp.feet to get sum of inches from object d1 and d2 And feet from object d1 and d2. Finally the object temp is returned so that in main(), this “temp” object will get assigned to “d3”. Means “temp” becomes “d3” in main.

This example becomes the demonstrator of a member function -> (1) Having passed objects as its parameters as well as (2) It will return an object too.

One thing should be kept in mind , about this example as … In main() we have 1 statement as follows -> d3 = d3.sumdist(d1 , d2); This statement passes objects d1 and d2 of class distance and will return “temp” object and then will assign this “temp” object to “d3” object. As sumdist() function is not called before this atatement , we also can give following statements d3 = d1.sumdist(d1 , d2);

or even d3 = d2.sumdist(d1 , d2); All above 3 statements will give same answer. But it is better to use 1st statement for clarity. ♠ Object to object assignment -> Suppose we have declared 2 objects of same class , and we want to copy all contains of one object to all respective contains of other object, then there is no need of piece by piece assignment. We can directly assign one object’s name to another object’s name just by equal sign. Then all contents of other object. But provided both objects must be of same class. So that 3 data and functions will be same. e.g. -> # include <iostream.h> class distance { private : int feet; float inches; public : void getdist() { cout << “Enter feet :” << “\n”; cin >> feet; } void showdist()

Page 40: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 40 By V. D. Gokhale

ASTROMEDICOMP

{ cout << “Distance =” << feet << “-“ << inches << “\n”; }

}; void main() { distance d1 , d2; d1.getdistance(); Here d1 and d2 are of same “distance” class type objects. Now

suppose we want to copy all contains of d1 to d2 , there is no need of saying… d1.inches = d2.inches; d1.feet = d2.feet; For these 2 statements we can

just say. d1 = d2; d1.showdist(); d2.showdist(); } Just assign 2 objects by equal sign.

This property of objects and classes also behave like structures. We also can assign 2 structures having same elements.

• When object to object coping takes place , data member of 2 objects get different addresses in memory, but function members store name addressed as functions do not hold any value.

• Note that :- When 1 object is copied to another object of the same class , then data members get copied, but not the functions. Means d1.feet will get copied to d2.feet and d1.inches get copied to d2.inches. But d1.getdistance() and d2.showdistance() will not get copied as d2.getdistance() and d2.showdistance(). Because data holds some value while function names do not. Suppose d1.feet is stored at memory address 1012, d1.inches at 2166, d1.getdistance() at 2500 and d1.showdistance() at 3010. Then after copying in d2 object [ by d2 = d1 ] , d2.feet will have different address than d1.feet, similarly d2.inches will have different address than d1.inches. But as function names do not hold any data both d1 and d2 object function will have same memory addressed 2500 and 3010 respectively.

♠ Classes , objects and memory :- When we declare 3 objects of same class as distance d1 , d2 , d3; we may thought that in memory 3 separate copies of every

Page 41: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 41 By V. D. Gokhale

ASTROMEDICOMP

item is made. This will waste much memory when we will create as mush objects of the same class, say array of objects. But this not happen in memory. Actually the data items of every object is copied separate times for every object. But member functions are copied only once. Separate copies will occurs when we actually use member functions for different objects. ♠ Static class members :- [i.e. Static member data and static member functions.] As we now know that whenever 2 or more objects are created, separate memory gets assigned to the data items (only) of each separate object. But sometimes it may be necessary that , a data item (not all data items) should be unique to all objects of same class. Means if such unique data item is of integer type and if it has value 7 then d1.data = 7 , d2.data = 7 and so on. Means every object have 7 value for this data variable though any number of objects are defined. This can be done by mentioning such data item as “static”. e.g. :- # include <iostream.h> class distance { private : static int count = 7; -> Initialization with “static”. int feet; float inches; public : void getdata() { cout << “Enter Feet :” << “\n”; cin >> feet; cout << “Enter Inches :” << “\n”; cin >> inches; } void showdata() { cout << “Count =” << count << “\n”; cout << “Distance =” << feet << “-“ << inches << “\n”; } }; void main() { distance d1 , d2 , d3; d1.getdata();

d2.getdata(); d3.getdata(); d1.showdata();

Page 42: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 42 By V. D. Gokhale

ASTROMEDICOMP

d2.showdata(); d3.showdata();

} In the output of this program -> “Distance = statement will show

different values as user enters different values. But the 1st “cout” statement, will show the value of count as 7 , though d1 , d2 , d3 are 3 different objects. Thus “static” keyword makes utilization of such a data item which should be seen same for all objects. In memory too, though this is a data item, it is not created multiple times as number of objects. But it gets created once.

• Suppose in a car race where the blue print of car is “class” and cars are objects , then a car (an object) wants to know how many remaining cars are in race, similarly every running car wants to know how many cars are running in this race, then a number of running cars should be supplied to all cars (means to all objects) and that number must be constant to all cars (“static” to all objects).

• On the same line , if a function is to know for all objects it can be made “static” too. But there are many limitations on this. Like , a static member function can access only “static data” in that class, also they do not have “this” pointer and importantly “static” and “non static” versions of same functions can not be made. Hence they are less used in practice. But using static member data and static member function together can “pre initialized” the private static data before creation of object. # include <iostream.h> class stat { private : static int i; -> Static member data. public : static void init(int x) { i = x; } -> Static member function. void show() { cout << i << “\n”; } }; int stat :: i; -> Global definition of i of

class stat type. void main() { stat :: init(100); -> Initialization of “init”

function before any object is created. This function gives value of I as 100.

Page 43: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 43 By V. D. Gokhale

ASTROMEDICOMP

stat s; -> Now object “s” is defined of stat class type.

s.show(); -> This will give output as 100.

} • Static data member and function belongs to whole class and not to object.

Hence can be used even if object are not declared. • When a member function is static , it can only access static member data of the

same class. But the surprising thing is that , static functions need not object to access by “.” Operator . They can be directly accessed by using <class name> :: <static member function name>(); i.e. using scope resolution operator.

♥Nested class :- It is possible (like nested structure) to define one class in another class. This is known as “Nested class”. But “Inheritance” property of a class is very powerful, hence nesting is not necessary at all. Thus “Nested classes” are not used in practice. ♥ Local classes :- Instead of declaring globally (before main) , when a class in declared inside a function (including main) then that class is known as local class. Such class is known to the function only , in which it is declared. There are many restrictions on local classes – (1) All member functions must be declared and define inside the class. Means

we can not use scope resolution operator to write function body outside the class.

(2) The local class is not able to access local variables of that function, in which it is declared (except “static” local variables)

(3) No static variables can be declared inside a local class. For all above limitations, local classes are theoretically true , but not used in practice at all.

♣ Friend Functions :- When we declare a class, we declare member data items and member functions concerned with that member data too. But in a program some functions may be written are not member of any class. Such functions are known as Non Member Functions. [ non member functions include ->

(1) A function which is not member of any class or (2) A function which is not member of “A” class but member of “B” class , then

it is member of “b” but nonmember of “A” class. ] We also know that “private data of a class is accessible only to member functions of that class [ not even main can access that private data. ]”.

Page 44: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 44 By V. D. Gokhale

ASTROMEDICOMP

Now , problem will arise, when a nonmember function wants to access private data of a class. In such a cases, this problem will have solution if that nonmember function is made “friend” of that class, private data of which we want to access. This can be materialized by…..

Declare the nonmember function’s prototype inside the class [ private data of which we want to access ] with the key word friend at the beginning of prototype. It does not matter whether the declaration of friend function is in private or public section of class.

Definition and function body representation is as usual though this “friend” non member function has its prototype in the desired class there is no need of scope resolution operator fro defining and function body of class. This nonmember function can be written any where as usual.

A member function of one class which is non member for other class can be made accessible to its private data by making “friend” function.

• As friend functions attack on the data hiding feature of OOP, they must be used as less as possible. Instead , use inheritance.

• The situation for friend function use -> When a function has objects of 2 or more different classes as its parameter and there is no inheritance between these parameters classes. Means when the parameter classes are totally unrelated….

e.g. # include <iostream.h> class myclass { private : int a , b; public : friend int sum(myclass); -> Friend function. void setdata(int , int); }; void main() { int i = 3 , j = 4; myclass n; n.setdata(i , j); cout << sum(n) << “\n”; } int sum(myclass x) -> As this is not member function of { myclass, it can be declared as it is.

Page 45: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 45 By V. D. Gokhale

ASTROMEDICOMP

int num; But as it is “friend” of myclass, it can num = x.a + x.b; access private data (a & b) of objects return(num); of myclass. } void myclass :: setdata(int p , int q) -> This is a member function { of myclass and defined a = p; outside the class, hence b = q; use of scope resolution } operator is must.

In above example , “sum” is a nonmember function for myclass. But its prototype is defined inside the class and with “friend” key word. Hence now “sum” can access a , b private data of any object of myclass.

Though a friend function can access private data of a class , the data member can not be accessed directly by t heir names as a and b, but they should be accessed though object of that class as x.a and x.b.

♣ Friend classes :- On the similar lines of friend functions, one class may be friend of another class or 2 classes may be friends of each other. So that private data of one class can be accessible to member functions of another class. To do this…

(1) Declare the class name inside the other class body by <friend> <class> <class name>; this syntax

(2) Like friend function, the friend class can be defined elsewhere. e.g. -> # include <iostream.h> class amount; class coins; { private : enum units {penny , nickel , dime , quarter , dollar}; friend class amount; -> Class amount is now

friend of class coins. }; class amount { If it is already declare as private : coins :: units money; class amount; then this

Page 46: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 46 By V. D. Gokhale

ASTROMEDICOMP

public : “class” word is not necessary. We just can say friend amount;

};

(3) Usually declare friend class 1st and then the other class. Means in above code when compiler arrives at statement friend class amount; it can not see class amount as it is not declared before this statement. ( This is not true for all compilers ). If you don’t want to declare friend class as a whole then just write class amount; before class coins and then write declaration of class amount anywhere you want.

ARRAYS • Properties and utilities of arrays in “C” and “C++” are quite similar. Here we

will see the differences only. • When we want a specific sized array, it is better to define the size as const int

and then use that variable in the square brackets of array name. e.g. -> # include <iostream.h> const int SIZE = 100; -> The array size variable is declared. float sales [SIZE]; -> This means that array sales will contain 100

floating numbers. o Same size variable then can be used in loops too.

like…. for(i=0;i<=SIZE;++i);

o As array size is always “integer” type, we must use “int” with “const”. The keyword “const” makes this array size variable permanent valued number, which will not get changed throughout the program.

o When you are going to use a size variable , instead of number, it is better to write the variable in “Capital Letters”. This is just for better readability and clarity , so that programmer will know that the capital lettered variable if for array size.

♥Formatting output numbers :- On page 4 we saw a manipulator “setw” which can format the output text in tabular format. But to format output numbers with decimal points in a tabular form along with “setw” other 2 manipulators are used….

(i) setiosflags() -> This manipulator is a function , which is a member of “ios” class which is predefined in “iomanip.h” header file. Thus while using this function inclusion of “iomanip.h” is necessary.

Page 47: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 47 By V. D. Gokhale

ASTROMEDICOMP

This function should be used 2 parameters (a) fixed :- This flag prevents numbers to get printed in exponential

form like 3.45e3. They will get printed in decimal form only. (b) showpoint -> This flag will place always a decimal point in

number. Because if the number is real (float or double) then the decimal point will appear as it is. But if the numbers are integer , then there will be no decimal point in display. If we want integer numbers and real numbers together to output in tabular form, then this flag inserts decimal point in integer numbers too. Means the number 42 , after using this flag will get output as 42.0 Now these 2 flags and setiosflags() function should be used ? ->

(1) As we use this in output, obviously they should be used with “cout <<” statement.

(2) While passing flags to he function, as these flags are from “ios” class “scope resolution operator” should be used along with them , as ……….. setiosflags(ios::fixed) -> prevents exponentiation setiosflags(ios::showpoint) -> always puts decimal

point. (3) As the numbers which we want to output are going to

appear afterwards don’t give semicolon until the end of “cout” statement.

(ii) setprecision() -> The manipulator function is used to decide , how many digits you want after a decimal point. The desired number of digits are passed as parameter to this function. e.g. -> If you want the number 3.456789 as 3.45 then before the number , the “cout” statement should be used along with setprecision(2) so that 2 numbers will get displayed (out of all other numbers) after the decimal point.

(iii) setw() -> This function manipulator is already explained on page no 4. This is used to decide the total number width [ i.e. digits left to decimal point + decimal point + digit right to decimal point ]. This width is also termed as field width.

• Generally all above manipulators are not used to display a single number , but they are used to create a table when you want to display numbers from an array. e.g. -> Suppose you want to display the array elements from an array say …… up to 2 digits to right of decimal point….. and field width of 10. float sales[100][3]; Then the usage of above manipulators will be int I , j;

Page 48: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 48 By V. D. Gokhale

ASTROMEDICOMP

for(i=0;i<=99;++i) { for(j=0;j<=2;++j) { cout << setiosflags(ios::fixed) << setiosflags(ios::showpoint) << setprecision(2) << setw(10) << sales[i][j]; -> Semicolon finally. } -> end of inner for loop (of j) } -> end of outer for loop (of j) Note -> The “cout” statement , though written an separate 5 lines, it is one “cout” statement. Hence semicolon is given at the termination of “cout” statement. If wish, this statement can be written in one line too. But above approach is better for readability and clarity.

• Declaration of function with array as its arguments :- (1) When single dimensional array is passed -> This can be

done by 2 ways… (a) <return type> <function name> (<data type of

array> < array size in square brackets>); (b) Same as above. Only in place of array size we can only

write empty square brackets too. (2) when multidimensional array is passed -> This can be done

by 2 ways. [ Same as above.] (a) <return type> <function name> (<data type of

array> < row size in square brackets> < column size in square brackets>).

(b) Same as above. But row size in square brackets can be eliminated, keeping empty square brackets only. Though it is “column size” must be given.

• Making function call of array as argument :- While calling a function in program, just mention the name of array in

the round brackets of function. There is no need of sizes and square brackets in function call.

• Writing function body , of function as array argument :- While writing function body,

<return type> <function name> (<data type of array> <desired array name> <but row size and column size must be same as original array>)

{

Page 49: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 49 By V. D. Gokhale

ASTROMEDICOMP

function body. }

• Array as class member data :- Any type of array can be member data of a class. To access that array

item, obviously we should use different loops. But note that if loops having functions are defined with their function bodies in the body of class, then compiler gives error “Loop variables can not be made inline”. This error occurs because , functions written in the class are default inline and loops are not allowed in inline functions. Thus loop having member functions should be defined elsewhere using scope resolution operator. But their function prototype must be written in the body of class.

• Array of objects :- While writing program we declare objects of a class like….

distance d1 , d2 , d3; But suppose there are many objects of same class, then we can declare array of objects too. Like…

distance d[20]; This declaration indicates that there are 20 objects of distance class. Now to access these objects in our program , we should use loops, such as… for(i=0;i<20;i++) {

cout << d[i].setdata(); -> setdata() and showdata() are cout << d[i].showdata(); member functions of class distance.

} Note ->

• Care should be taken for array size. Because C++ does not check array bounds and if overflowed , then system may hang or crash.

• This is just similar to structures as ….. (1) Structures may contain arrays. (2) There may be array of structures.

STRINGS From “C”, we know that “String is nothing but the array of character

data.” All ideas about strings in “C” and “C++” are similar. All strings terminate by NULL character, i.e. ‘\0’; Though string is an array, it can be accessed just by mentioning its

name (which has base address.) e.g. “cout << str or cin >> str” are perfectly valid.

Page 50: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 50 By V. D. Gokhale

ASTROMEDICOMP

While declaring , string should be declared as array of “char” data type, followed by string name, then square brackets [ which may be filled with array size or may be kept empty] and finally semicolon.

If initialized at the time of declaration , then braces are not necessary. Only pair of “ “ are necessary. e.g. -> char str[] = “Dr. Vijay D. Gokhale”;

Reading a string having blank spaces :- There is no problem in outputting the string , both in “C” and in “C++”. There is also no problem in inputting a “string without blank”, both in “C” and in “C++”.

But there is problem in input of such a string which has blank spaces in it. Both “scanf()” in “C” and cin >> in “C++” can not read such string.

If we input a string “Dr. Vijay D. Gokhale”, then both “scanf()” and “cin” functions read this string upto 1st blank only. Thuis when we use

output functions such as “printf()” or “cout” we get only “Dr. Vijay” not the whole string.

To overcome this problem we use “gets()” function for input of “blank space having string”. This function also works in C++ , if we include “stdio.h” header file.

But pure C++ , provide another way to input such string and that is “get()” function.

get() -> (not gets()) While input of “blank space having string” this function should be used along with “cin” operator as cin.get (parameters). Here the dot operator is also used. The parameter to this get() function are 1st string name and second string size which we give at the beginning of our program. Usually we do not know in advance , what sized string user will input. Hence for the sake of safety we declare string array size maximum to say 90 or 100. Then this maximum size should used as 2nd parameter to the get() function. e.g. # include <iostream.h> const int MAX = 100; void main() { char str[MAX]; cout << “Enter a string :” << “\n”; cin.get(str , MAX); cout << “You entered :” << str << “\n”; }

Reading multiple lines of a text like string :-

Page 51: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 51 By V. D. Gokhale

ASTROMEDICOMP

In previous example we saw how to read (input) the string with blank spaces. But what about a string with multiple lines ? Because when a user will input one line, he/she will press enter and our cin.get() function will take that whole line as an inpu string. But if string has more lines, then those can not be read. To overcome this problem, the get() function takes 3rd parameter which is a character. The default is “\n” character, which is a new line character. But C++ does not force you to use this character as 3rd parameter to get() function. You can choose any character , say ‘$’ (dollar sign). Only you have to do, is to chose such character, type this character as 3rd parameter to get() function and than enter as many lines as you want. After each line now you can press enter with no hesitation. cin.get() function will stop reading string when your string will terminate and then you enter the chosen character as your string termination indicator. e.g. -> # include <iostream.h> const int MAX = 100; void main() { char str[MAX]; cout << “Enter few lines of text :” << “\n”; cin.get(str , MAX , ‘$’); cout << “You entered following text :” << “\n”; cout << str; } [ While renning this program , terminate input text by $ ] Note -> though this mechanism will terminate output when cin.get() will face character termination, it is your duty, not to enter text beyond the specified array size. Other wise cin.get() may stop in between.

Other features about strings like “Coping a string finding length of string , array of strings , programs of strings using pointers , using array index” are similar as like in “C”. Only use syntax of “C++” in place of “C”.

Strings as class members :- Just like other data types , a string can be a member of class too. To use these strings we may use library functions like strlen(), strcpy() etc. Only the string iis that , unlike in “C” , here we must include “string.h” header file before using any string library functions. While passing a string to any function as its parameter you

Page 52: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 52 By V. D. Gokhale

ASTROMEDICOMP

can use “char <string name>[]” syntax in the rounded brackets of that respective function.

User defined string type :- This is some what new feature in C++. Two strings can be assigned just by equal sign in C++. If s1 is 1 string and s2 is another string , then we can not say s1 = s2 in C++. To do this we have to use “strcpy” function. But to make it easier like s1 = s2, we should learn “Operator Overloading” which we are going to see in next chapter.

• Bit wise Operator :- o & -> Bit wise AND. o | -> Bit wise OR. o ^ -> Bit wise exclusive OR or XOR. o ~ -> One’s complement.

• Bit wise shift operator :- o << -> Left shift operator. o >> -> Right shift operator.

• Additional short hand operator :- o <<= -> Shift left assignment. o >>= -> Shift right assignment. o &= -> Bit wise AND assignment. o |= -> Bit wise OR assignment. o ^= -> Bit wise XOR assignment.

OPERATOR-OVERLOADING

INTRODUCTION We can use all logical, compulsion & arithmetic operators as they are, for the built in data types of C++, like int, float, double, char. But we can’t use them with user defined data types. Means, if d1, d2 & d3 are objects of class distance, then we can’t say “d3=d1+d2;” directly, because d1, d2, d3 are user defined data types. Similar rule is for struct & enum variables too. But, C++ has a classic future, by which we can force these operators to get operated on user defined data types too, keeping their previous activity as it is. This future is known as OPERATOR OVERLOADING which is a new way to define our

Page 53: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 53 By V. D. Gokhale

ASTROMEDICOMP

own C++ language. Operator Overloading resembles with function overloading. Hence if we know function overloading well, then we can very well grasp the idea of operator overloading too. ** How Operator Overloading Is Done? 1> The medium of operator overloading is a function. Hence the declaration of operator overloading function should be done in the respective class, objects on which we are going to use overloaded operator. 2> The function should be written in class either only decelerator [& function body else where with scope resolution operator] or function should be declared & defined as well in the class itself. 3> Member Function writing starts with… if written inside the class

a) return type of function b) space c) the key word operator d) operator itself (eg. = + or – or += etc) e) opening round bracket f) one parameter g) closing round bracket h) opening brace i) statement of necessary operations i.e. function body j) closing brace

That is… <return type> operator <operator itself> (only one parameter) { operations (function body) }

…but if written outside the class.

a) return type b) space c) class name * d) scope resolution operator * e) the key word operator f) operator itself ( i.e. + or – or += etc.) g) opening round bracket – only one parameter – closing round bracket h) opening brace i) statements of necessary operations i.e. function body j) closing brace

That is… <return type> <class name> :: operator <operator itself> (one parameter)

Page 54: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 54 By V. D. Gokhale

ASTROMEDICOMP

{ operations (function body); } 4> Note That a) If we want to overload unary operators, means increment operator (++) or decrement operator (--) or unary minus operator (-), then we have 2 situations

i) prefix, means ++x; or –x; ii) postfix, means x++; or x--;

Then in prefix operator overloading there is no parameter list . <return type> operator <operator itself> ( ) no parameters { body of prefix operator }

In Postfix operator overloading there should be one parameter “int”. Only this word is enough means…. (dummy parameter) <return type> operator <operator itself> ( int ) { body of postfix operator } b) When we are going to overload Binary Operators like +, -, then we know that there are two operands like a+b, here “a” is left sided operand and “b” is right sided operand. [Obviously a & b are objects of same class] Now when we overload these operators, the left sided operand is taken by the function as it is. [means no need of parameter for this operand] How this happens? When we overload these operators, left sided operand is passed to the overloaded function by “this” pointer. Obviously right sided operand should be passed explicitly to the “overloaded function” as a separate parameter in parameter list. c) point (3), (4)a & (4)b are for that type of operator overloading function which is obviously a member function of a class [either declared & defined in the class or declared in the class but defined else where using scope resolution operator]. But some times it may be necessary, that an operator overloading function access the class data but not a member function [means a nonmember function], then….

As such nonmember function accesses the class member data, it must be friend of that class. Thus it should be declared inside the class using the keyword friend and then its function body should be written.

We know that (1) In case of Unary operator overloading, the operand is one and it is passed as it is to the function body by “this” pointer.

Page 55: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 55 By V. D. Gokhale

ASTROMEDICOMP

(2) In case of Binary operator overloading, the left sided operand is passed to the function by “this” pointer, while right sided operand is passed as a parameter via parameter list. But above rules (1) & (2) are true for member functions only. For a nonmember but friend function of operator overloading…. (1) For Unary Operator this operand must be passed using reference Eg. void operator ++() -> True for member but false for nonmember friend void operand ++(distance& d) -> the operand is passed by reference to a nonmember but friend operator overloading function (2) For Binary Operator both operands must be passed as a parameter Eg. void operator + (distance d) -> True for member but false for nonmember friend void operator + (distance dx, distance dy) -> Both operands are passed as parameters to a nonmember but friend operator overloading function.

*** The difference between member and nonmember operator overloading function, is due to the fact that, when function is member, compiler knows its objects by “this” pointer. But when a function is nonmember compiler can not know its objects by pointer. Hence to give information about objects, such functions require objects as parameters.

5> Call to Operator Overloading Functions whenever the operator in front of the operator keyword, in function declaration, appear in the program, the operator overloading function is called. Eg. If we have objects a & b of class c, and suppose we overload operator “+” by…

c operator + (c bx); -> here keyword “c” denotes that this function will return object of “c” type class.

void main() {

1st call to c a, b, ab; a,b,ab are 3 objects of “c” type. “+” (pure ->ab = a + b; Here objects a & b are summed by “+” operator objects) int n1, n2, n3; n1 = 5; 2nd call to n2 = 10; “+” (pure ->n3 = n1 + n2; Here integers n1 & n2 are summed by “+” operator objects) }

Page 56: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 56 By V. D. Gokhale

ASTROMEDICOMP

In above, “+” is called twice. First it does sum of objects a & b, which are of user defined type. Hence compiler when comes across this “+”, it thinks about (1) whether to operate usual “+” operation or (2) to operate overloaded “+” operation. In this thought it sees operands, as soon as it realizes that operands are not of built in data types, but are of user defined types, it executes overloaded version of “+”, which is defined else where. When the compiler sees further “+” again it observes operands. In 2nd “+” operands are integers, which are built in data types. Hence it does not execute the overloaded version of “+” but executes the usual “+” operation. The above principle is most important principle in operator overloading and is unique to all types of operands. 6> Overloading operator functions can be called any times. Eg. If a, b, c, d are objects of same class, then d = a + b + c; Here overloaded operator is called twice in single equation. 7> Which operators can never be overloaded :- a) The dot operator [member access operator] -> . b) The scope resolution operator [Double colon] -> :: c) The cinditional Operators -> ? & : d) The pointer to member operators -> . * Above 4 operators can not be overloaded. But ++, --, +, -, =, *+=, -=, , , (), [], new, delete, ->, <, >, =<, >=, != operators can be overloaded. ( also size of operator can not be overloaded) Now we will see some examples of important operator overloading functions… ** Example Program Of OPERATOR OVERLOADING This program includes overloading of 3 Binary & Unary operators.

i) Overloading of Binary “+” operator ii) Overloading of Binary “-” operator iii) Overloading of Binary “=” operator (Assignment operator) iv) Overloading of Binary “++” operator (increment operator)

# include < iostream.h > class loc { private : int longitude,latitude; public : void getdata() {

cout << “ENTER LONGITUDE : “ << “\n”; cin >> longitude; cout << “ENTER LATITUDE : ” << “\n”;

Page 57: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 57 By V. D. Gokhale

ASTROMEDICOMP

cin >> latitude; } void showdata() {

cout << “LONGITUDE = “<< longitude << “\n”; cout << “LATITUDE = “<< latitude << “\n”;

} loc operator + (loc op2); loc operator - (loc op2); As function prototypes are defined in the loc operator = (loc op2); class and their bodies elsewhere. loc operator ++ (); }; // End of class declaration loc loc :: operator + ( loc op2) { loc temp; temp.longitude = longitude + op2.longitude; temp.latitude = latitude + op2.latitude; return (temp); } loc loc :: operator - ( loc op2) { loc temp; temp.longitude = longitude - op2.longitude; temp.latitude = latitude - op2.latitude; return (temp); } loc loc :: operator = ( loc op2) { longitude = op2.longitude; latitude = op2.latitude; return (*this); } loc loc :: operator ++ ( loc op2) { ++longitude; ++latitude; return (*this); } void main()

Page 58: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 58 By V. D. Gokhale

ASTROMEDICOMP

{ loc ob1, ob2, ob3; ob1.getdata() Suppose user enters longitude 50 and latitude 50. ob2.getdata() Suppose user enters longitude 100 and latitude 100. ob3 = ob1 + ob2; call to overloaded “+” operator function ob3.showdata(); Answer will be, longitude 150 and latitude 150 [50 + 100] ob3 = ob2 – ob1; call to overloaded “-” operator function ob3.showdata(); Answer will be, longitude 50 and latitude 50 [100 – 50] ob1 = ob2; call to overloaded “=” operator function ob1.showdata; Answer will be, longitude 100 and latitude 100 ob2 = ++ob1; call to overloaded “++” operator function ob1.showdata(); answer will be 101 & 101 ++ob2; call to overloaded “++” operator function again ob2.showdata(); answer will be 102 & 102 } We can learn so many things about operator overloading from above program… * (A) About Declaring Operator Overloading Functions in a Class In this class, named “loc”. This class has 2 private data members longitude & latitude, which are of “int” type. Then it has 6 member function, out of which two are usual getdata() & showdata(), while remaining four functions are of operator overloading,

The declaration of four operator overloading functions are done only with their prototypes, means their function bodies are defined outside the class by using :: scope resolution operator.

All these declarations starts with class name, means all of these functions have return type of an object of class “loc” type.

while declaring these functions as their prototypes we pass an object “op2” of class “loc” type in the parameter list. [this is only about binary +, - & = operator functions]. Here “op2” word is optional. Means we can make these three declarations as… loc operator + (loc); loc operator - (loc); “op2” word is optional loc operator = (loc);

Though +, - & = are binary operators means, they require 2 operands, we pass one of them, then how can it access the remaining one operand?

Page 59: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 59 By V. D. Gokhale

ASTROMEDICOMP

The answer is -> There are 2 operands on each side of these operators. One at left side of operator and other at right side of operator. By default C++ compiler recognizes the left sided operand by this pointer. This left sided operand calls the overloading function. Now question remain about, how C++ compiler can recognize about right side operand? The answer is that we have to pass this right side operand as the function parameter. Hence we pass one (right sided) and compiler recognizes one as it is (left sided) and thus 2 operands are accessed. Thus when we want to overload binary operator we must pass right sided operand as the function parameter. But this is true only for member functions. Here all are member functions. Suppose these are nonmember functions, then compiler can not use “this” pointer to recognize the left side operand. Hence in such cases we have to pass both parameters as function parameters. Then the declaration will be… ->> friend loc operator + (loc op1, loc op2); or friend loc operator + (loc , loc ); ->> friend loc operator - (loc op1, loc op2); or friend loc operator - (loc , loc ); ->> friend loc operator = (loc op1, loc op2); or friend loc operator = (loc , loc );

• While dealing with “+” sign, while passing parameters, there is no question about which is first op1 or op2. Because 3 + 5 = 8 & 5 + 3 = 8.

• But while dealing with “-“ & “=” operators, the matter of 1st & 2nd is important. Because it is the programmer’s duty to consider which object is to be subtracted from which object AND which object to be assigned equal to which object.

(* NOTE while overloading “-“ operator, always subtract “passed operator” from “intaken operator”)

* (B) About Defining Operator Overloading Functions In this program only prototypes of functions are written in the class and these functions are defined with their function bodies outside the class using :: scope resolution operator. This is done just for there sake of readability & clarity. As there function bodies are small, we may declare & define them inside the class too (inline). But if their function bodies are large, then it is better to define their function bodies as shown in this program.

Hence we made all functions to return an object of the same “loc” type class. But it we declare “+” operator overloading function as shown in this example program. Then in main() program, we can also call this function as (ob1 + ob2).showdata(); Here “ob1” will call “+” function and will be recognized by compiler using “this” pointer and “ob2” will be passed as right side operand. In the function body, the first return type “loc” will get changed to “void”. There remains no need of “temp” object

Page 60: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 60 By V. D. Gokhale

ASTROMEDICOMP

and there will be no return statement. The body will look like… we can use “return (*this);”

loc loc :: operator + ( loc op2) {

longit ude = longitude + op2.longitude; latitude = latitude + op2.latitude;

} -> No return statement will give warning. Hence it is better to type (return * this);

The answer will be directly displayed by showdata() But note that as we call showdata() directly by “ob1 + ob2” the new values (after addition) will not get stored anywhere. If we want to store them, then we must store them into object and that object is assigned to the sum by equal sign with other objects as shown in this program, like ob3 = ob1 + ob2. Here the values in “temp” object are given to object ob3. The same philosophy applies to “-” operator overloading too.

When we use “=” operator, we actually assign one’s value into the other’s. Here when we call “=” function by ob1 = ob2, then we want that values in ob2 should be assigned to values in ob1, changing original values of ob1. As “ob1” is on left side, its data will be recognized by the compiler by “this” pointer and the ob2 is passed as right side operand. In case of “=” operator, there is no need of storing value in some another object. Hence in function body, there is no need of “temp” object. Then how this function works? When we say… longitude = op2.longitude; Then compiler knows that the word “longitude” is nothing but “ob1.longitude”. It overwrites its original value by the value of “ob2.longitude” [which comes from op2.longitude]. Same happens about “latitude”. After calculation, we want to return these new “longitude” & “latitude” data items of “ob1” object to the program. Indirectly we want to return these values given by “this” pointer previously. As pointer can directly reflect changes made in values, if we return “this” pointer, the changed values will get obviously returned back to “ob1” as it is a left side operand. Hence the statement return(* this); is used here. As “this” pointer points to an object of class “loc” type, the word “loc” as a return type is must in the declaration of “=” operator overloading function ( loc operator = (loc) ) Some program function can be written just by changing “loc” to “void” and eliminating the “return(*this);” statement. This approach can also work, because as this function is a member function, it can directly access the data items & changes made in it. void loc :: operator = (loc op2) { longitude = op2.longitude;

Page 61: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 61 By V. D. Gokhale

ASTROMEDICOMP

latitude = op2.latitude; } In this example program we use “++” unary operator, and use it in “prefix” [++x] form. When we use unary operator, then there is only one operand, which calls this function. As this only one operand can be directly recognized by the compiler, there is no need of parameter usually. But when we use “++” or “—“ operators how compiler can know that we are going to use it as “prefix” or as “postfix”? To give answer of this question Stroustrup gives a solution. While declaring operator overloading function for “prefix” ++ or --, there should be no argument (parameter), while declaring “postfix” ++ or – operator overloading function there should be one parameter to these functions as “int”. The use of this parameter to in the function body is optional. Because this “int” parameter is automatically assigned to 0 by the compiler. But this is the only way that compiler can distinguish between “prefix” and “postfix” operator overloading functions. Although in case of Turbo C++ & Borland C++, the effective answer of ++x & x++ operator overloading is one and the same. Hence using these compiler “int” parameter is optional too. This is limitation of these 2 compilers. While writing the function body there is no need of using this “int” variable. We use this type of operator overloading as ob2 = ++ob1; because we made this function for return an object of “class loc” type and we want to store this value. Hence return (*this); statement is also used. The same function also can be written, with same effect as … void operator ++(); & its body -> void loc :: operator ++ () { ++longitude; ++latitude; } no return statement By this way we can call “++” operator as ++ob1 or ob1++ or ++ob1.showdata() or ob1++.showdata() But we can’t use ob1 = ++ob2; because no return object statement is used. Hence if we want to increment or decrement an object & store the new value in different object, then follow the method in this example.

An above discussion of point (B) is made uptill for member functions. For nonmember functions ->

(1) Declaration should be made in the class, storing with keyword “friend”. (2) In case of Unary Operator, parameter is must and should be passed by

reference as… friend loc operator ++ (loc &); (3) In case of Binary Operators, both operands must be passed as parameters,

taking care about their sequence in the function body. (4) Function bodies should be written with using both parameters and by the

method described during Friend Functions

Page 62: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 62 By V. D. Gokhale

ASTROMEDICOMP

* Suppose “+” operator overloading function is nonmember but friend function of class “loc”… # include <iostream.h> class loc { :

friend loc operator + (loc, loc); declaration with passed both : operands as parameters

: }; loc operator + (loc op1, loc op2) as normal function { loc temp; temp.longitude = op1.longitude + op2.longitude;

temp.latitude = op1.latitude + op2.latitude; return (temp);

} void main() { loc ob1, ob2, ob3; ob1.getdata(); ob2.getdata(); ob3 = ob1 + ob2; ob3.showdata(); }

[NOTE -> “=”, “()”, “[]”,”->” these operators can not be overloaded using “friend”] * Suppose “++” operator overloading function is a nonmember but a friend function of class “loc”…

# include <iostream.h> class loc { :

friend loc operator ++ (loc &); one operand is passed by reference :

: }; loc operator ++ (loc op) {

++op.longitude; ++op.latitude;

Page 63: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 63 By V. D. Gokhale

ASTROMEDICOMP

return (op); returns new values of passed operands } by return(op); statement

NOTE In all above discussions we use Unary & Binary operators to get overloaded to do their functions on user defined data types, such as objects of class. But when we say ob3 = ob1 + ob2; note that data items of object ob1 will get added to data items of object ob2, and not member functions. Means the overloaded operators will obviously work on member data items of objects and will not work on member functions of objects. * Overloading Comparison Operator :- As like other operators we can not use comparison operator for user defined data types. Means if a & b are two objects of class, we can’t say a<b or a>b. To do so, we have to force these operators to compare for objects too. For this purpose we have to overload comparison operator. As an example, here we will overload “<” [less than] operator… # include <iostream.h> enum boolean {false, true}; declaration of user defined variable globally. class distance { private : int feet; float inches; public : void getdist() { cout << “ENTER FEET : “ << “\n”; cin >> feet; cout << “ENTER INCHES : “ << “\n”; cin >> inches; } void showdist() { cout << Distance = “ << feet << “-“ << inches << “\n”; } boolean operator < (distance); overload operator function returns Boolean type. }; void main() { distance d1, d2; d1.getdist(); d2.getdist();

Page 64: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 64 By V. D. Gokhale

ASTROMEDICOMP

d1.showdist(); d2.showdist(); if (d1 < d2) call to overload “<” operator function cout << “First Distance Is Less Than Second Distance.” << “\n”; else cout << “First Distance Is Greater Than Second Distance.” << “\n”; } boolean distance :: operator < ( distance d) { float dx, dy; dx = feet + inches/12; for total dist. of object passed by this pointer. dy = d.feet + d.inches/12; total dist. of 2nd object passed as parameter. if(dx < dy) return(true); else “true” and “false” are boolean type variables. return(false); } In this program we want to test a condition by “<” comparison operator. Hence first of all we declare a user defined variable “boolean” which has 2 values either “true” or “false”. As compiler knows enumerated variables by integer numbers, “false” resembles 0 and “true” resembles 1. then we declare operator overloaded function for “<” operator having return type as boolean variable. Comparison takes place always between 2 entries. Here these 2 entries are 2 objects. One object will be directly recognized by compiler by “this” pointer and another object is passed as parameter for this operator overloaded function. Hence we define the prototype as… boolean operator < (distance); return type keyword operator type of parameter (here object of class

distance type is parameter) While wrtting function definition, we use scope resolution operator, as

function is member but defined outside the class. In the function body variables “feet” & “inches” are used as member data of object passed by “this” pointer & d.feet & d.inches are member data of passed parameter object. Then using less than operator for total distance, we use “if-else” condition to return either “false” or “true” as boolean return type.

In main() program now we can use “<” operator to check condition between two objects d1 & d2 pf class distance type. * Concatenating 2 Strings Using Operator Overloading Of “+” Operator :-

Page 65: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 65 By V. D. Gokhale

ASTROMEDICOMP

Suppose user enters one string as “ABCDEF” & 2nd string as “GHIJKL” and suppose first string is s1 & 2nd string s2, then we can not say s3 = s1 + s2; to get the output as “ABCDEFGHIJKL”. To do so, means to add 2 strings to give a resultant string, we have to concatenate (join) two strings using “strcat()” library functions. But suppose we want to concatenate such 2 strings which are member data items of a class, then strcat() will not work with objects. So we should define such a function, which will just add 2 objects to give third objects and as well the function should join 2 strings in those third object. We can do this by using operator overloading of “+” operator. # include <stdio.h> for gets() function # include <string.h> for strcpy() & strcat() functions & for strlen() const int SIZE=80; maximum string size as array index class string { private : char str[SIZE]; public : void getstring()

{ cout << “ENTER A STRING :- “ << “\n”; gets(str);

} void showstring() { cout << “YOU ENTERED :- “ << “\n”; cout << str; } string operator + (string); An operator overloading function for “+” operator, }; which returns an object of class string type & which

accepts an object of class string type as its parameter void main() { string s1, s2, s3; 3 objects of class string type. s1.getstring(); s2.getstring(); s3 = s1 + s2; s3.showstring(); } string string :: operator + (string s) { string temp; object temp of string class type.

Page 66: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 66 By V. D. Gokhale

ASTROMEDICOMP

strcpy(temp.str,str); copies “str” of first object into temp.str strcat(temp.str,s.str); concatenate string in temp.str & s.str return (temp); return object “temp” which has concatenate 2 strings. } We declare a function which accepts an object of “string” class type as parameter (right sided operand) and which will accept another object (left sided operand) by “this” pointer. This function will return an object of “string” type, which will have the concatenated string. The function prototype is defined inside the class while function body is written outside the class using :: scope resolution operator. When compiler sees s3=s1+s2; it gets “str” member data of s1 by “this” pointer & “str” member data of s2 is passed to the function as its parameter (s.str). In the function body, a temporary object is created. The strcpy function copies “str” [which is nothing but “str” member data of s1 object] to temp.str. now temp.str has one string. Then function start concatenates the “str” in s.str [which is nothing but s2.str] with the temp.str. The resultant concatenated string is now in temp.str. “return(temp)” statement returns this object to main program and gives its values to s3 object as we use “=” sign here. NOTE User may enter 2 string which may exceed the total string size of 80 characters. To avoid this we may write following code for operator overloading function as… string string :: operator + (string s) {

string temp; strcpy(temp.str,str); if(strlen(str) + strlen(str) < SIZE)

{ strcat(temp.str,s.str); }

else { cout << “ARRAY SIZE OVERFLOW.” << “\N”; }

} This “if-else” block will concatenate the strings only when the total length of first string & second string is less than 80 characters. Otherwise it will give the message of overflow. If we want to do same above program, without using strcpy, strlen & strcat library functions, then refer to Notebook of “C”, which has 2 methods of string concatenation (1) Pointer, (2) Array index.

Page 67: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 67 By V. D. Gokhale

ASTROMEDICOMP

* DATA CONVERSION The basic data types like int, float, double & char can be interchanged between themselves using the property of “type casting” as explained before. But such inter conversion can not be possible between user defined data types. In such cases 3 situations may occure…

(1) Conversion of basic data types to objects of a class. (2) Conversion of objects of a class to basic data types. (3) Conversion of an object of one class to an object of other class. We can use the keyword “operator” for above situations too, just like in operator overloading.

(1) Conversion Of a basic data type to an object of a class This situation occurs when we have a variable of a basic data type and we want to covert it to a variable of an object of a class. Suppose “class distance” has data members “int feet” & “float inches” and user wants to enter the distance in meter as “float meter”. Now question occurs to convert this “meter” into “int feet” & “float inches” of an object. Such things can be made possible, just by declaring a function inside the class, which takes the basic data types as its parameters, convert that data type into member data items and returns these member data items together by returning an object of same class. Such conversion does not need help from “operator” keyword. Eg. # include <iostream.h> class distance { private : int feet; float inches; public : void getdistance() { cout << “ENTER FEET : “ << “\n”; cin >> feet; cout << “ENTER INCHES : “ << “\n”; cin >> inches; } void showdistance() { cout << Distance = “ << feet << “-“ << inches << “\n”; } distance convert (float ); converts float to distance type data members };

Page 68: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 68 By V. D. Gokhale

ASTROMEDICOMP

void main() { int choice; distance d1; float meter; cout << “Do You Want To Enter Distance In Feet-Inches Or In Meters? If In Feet-Inches, Press 0 If In Meters, Press 1 “ << “\n”; Cin >> choice; If(choice == 0) {

d1.getdistance(); }

if(choice == 1) { cout << “ENTER DISTANCE IN METERS : “; cin >> meter; d1 = convert(meter); } d1.showdistance(); } distance distance :: convert (float m) { float factor= 3.280833; Necessary constant to change meter to feet. float mtf; distance temp; mtf = factor * m; temp.feet = int(mtf); temp.inches = 12 * (mtf – temp.feet); return (temp); }

In this program we wrote a member function, which is public, hence we can use it anywhere in the program. This function accepts a floating point data and returns object of distance type. [This function can be a nonmember but friend function. In main() we give choice to user to enter the distance either in the form of “feet-inches” or in the form of “meters”. If user wants to enter the distance in “float-inches” form, then there is no problem, we can directly call “getdistance()” function. But if user wants to enter the distance in meters, then problem will arise. Here we can not use “getdistance()” function. In such a case we have to first take the distance in meter form, pass it to “convert” function. In this function we have to convert these

Page 69: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 69 By V. D. Gokhale

ASTROMEDICOMP

meters into respective feet & inches and store them in a temporary object and return that object. Means if user enters “feet-inches” then d1.feet & d1.inches will get directly by d1.getdistance() function. But if user enters meters then convert function will return of feet & inches of temp object which will then get assigned to d1 by d1=d1.convert(meters); statement. Hence to convert meter to “feet-inches” form [means from basic to object form], a constant is necessary, which when multiplied to meters, give feet. But these “feets” are “float” and feet in object are “int” hence we have to convert these “float feet” into “int feet” which is done by type casting. mtf = m * factor; feet = int ( mtf ); type casting Now while converting “float feet” into “int feet” the digits after floating point are ignored. We have to get them to convert them into inches. To get this fraction “int feet” should be first subtracted from “float feet” and this fraction then multiplied by 12 to get inches. (2) Conversion Of An Object Type Data To A Basic Type Data This situation occurs when we have an object of a class, which has a member data item of one data type and user wants that member data item to get converted into another data type of basic nature. Suppose we have a class “distance” which has 2 data members “int feet” & “float inches”. The user does not want the distance in “feet-inch” form, but wants the distance in “meters”. In main program we can not use feet and inches data of class, because it is of private nature. This situation also occurs when user wants the distance in both forms “feet-inches” and “meters”. Now a class member function which receives the distance in “feet-inches” form, can be easily displayed by another function in “feet-inches” form. But what about the answer in “meters” form? For a basic type casting we can easily say “num = float(n);” but for an object “a” we can not say “num = float(a);” because type casting is done between basic data types and not between user defined objects. Such things can be made possible with the help of “operator” keyword. Select the data type of conversion and declare a function inside the class as… operator <type cast data> () {

necessary conversion statements using class member data directly; return (the answer variable after type casting);

} The above format requires following points to keep in mind…

1) Conversion type cast function has no return type. 2) It should be generally declared & defined in the class. 3) It starts with the keyword “operator”.

Page 70: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 70 By V. D. Gokhale

ASTROMEDICOMP

4) The keyword operator is followed by a space and then followed by that data type in which the user wants the answer i.e. type casted data type.

5) As this function is defined & declared inside the class. It is a member function & thus can access the class member data directly. Thus it does not require any parameters in declaration. Just keep round brackets empty.

6) As we are going to define the function body inside the class, opening brace. 7) Now we can get necessary class data members directly, convert them to

required form by type casting and get the answer in a variable. 8) Return that answer variable by return(variable); statement. NOTE though,

in declaration, there is no return type, C++ compiler can return this answer variable directly to calling program.

9) Closing brace of function termination. 10) While using this function in program while making call to this type

casting function, (a) First of all, we are going to store the type casted answer in a variable

of type casted data type. Hence declare that variable first with respective typecasted data type.

(b) Then we are going to assign the value of the type casted object to this variable. Hence use assignment operator, “=”.

(c) Then type the word of type casted data type. (d) Opening round bracket. (e) The object name, whose type casting you want to do. (f) Closing round bracket (g) Semicolon termination.

When compiler faces above call, first it sees the “typecasted data type”, then it sees the object, as type casting is not allowed for user defined object, it can not manipulate its built-in type casting. Hence it searches for “operator” function for this user defined object type casting. When it founds that, it enters that function. Converts the object’s member data to desird type casted form, takes the answer of type casting in a variable and returns the answer variable back to the calling program. Now in calling program we use “=” assignment operator, hence it assigns this answer to the variable on the left side of “=” sign.

We will see all above 10 points by taking an example. The respective number of point is mentioned in front of respective step in program. So first read the program statement, then read the respective point for its explanation. # include <iostream.h> class distance { private : int feet; float inches;

Page 71: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 71 By V. D. Gokhale

ASTROMEDICOMP

public : void getdistance() { cout << “ENTER DISTANCE IN FEET : “ << “\n”; cin >> feet; cout << “ENTER DISTANCE IN INCHES : “ << “\n”; cin >> inches; } void showdistance() { cout << Distance = “ << feet << “-“ << inches << “\n”; } operator float() { float ft; ft = (feet + inches/12.0) / 3.280833; Points (1) to (9). return (ft); } }; void main() { float meters; point (10) a distance d1; object d1 of class distance type d1.getdistance(); get distance in “feet-inches” form d1.showdistance(); shows distance in “feet-inches” form meters = float(d1); convert feet-inches form to meters cout << SAME DISTANCE IN METERS = “ << meters << “\n”; shows distance } in meter form In class distance we declare a function using “operator” keyword. Here we use type casted data type as “float”. Means we want to convert the desired object data items into a “float” type answer. This is nothing but the overloading of “float” function which will now typecast objects too. In the function body we access “feet” & “inches” data member of respective object directly. Convert the answer to float form and store it in “ft” variable, which is returned by “return(ft);” statement. In main(), to store the answer of “float type casting of an object”, first we declare float variable “meters” and then declare an object “d1” of class “distance” type. Then by “d1.getdistance()” function we get the distance from the user in “feet-inches” form. By “d1.getdistance()” function we display the entered distance in “feet-inches” form.

Page 72: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 72 By V. D. Gokhale

ASTROMEDICOMP

* Now we want the same distance in meters form. Here we can’t say like… meters = (d1.feet + d1.inches/12.0)/3.280833;

Because main() is not member function of class distance and thus it can not access private variables of d1 object. Thus we say … meters = float (d1); By this statement, when compiler sees the word “float” and the data type “d1”, it neglects built-in type casting and enters in overloading function of “operators”. Though this functions, it can directly access the “feet” & “inches” variables of d1 object [NOTE -> these is no need of saying d1.feet & d1.inches in the operator overloading function]. Converts the data into desired form, returns it via “ft” variable and assigns it to “meters” variable, which can be now displayed by next “cout” statement. (3) Object To Object Conversion By overloading assignment operator “=” we can equate two objects of same class. But what about equating two objects of two different classes. When we do so, we have to convert one object’s data type of data members to another objects data types. If we do it as it is, compiler give error of type casting of one object’s data members. Suppose there is a class “a” and another class “b”. “objecta” is the object of “a” class and “objectb” is the object of “b” class. Then to say “objecta = objectb”, we have to do type casting. Here “=” says that the data members of “objecta” should change like data members of “objectb”. Means “objectb” is a source class and “objecta” is a destination class. In such circumstances we have write a function in source class which will convert source class data members to destination class data members, and will return it to destination class. * Declare Destination Class First & then Source Class. Then… * In source Class

(1) Write the keyword “operator”. Then type the name of “destination class”. [this does not mean that you are overloading “destination class”. Because classes can not be overloaded. Overloading can be done only of operator and functions. Here you are typing the name of class, after word operator, means you are overloading the constructor function. You know that constructor have same name as that of class.] Thus destination class name is nothing but constructor function name, which has same name as that of class. Then give a pair of empty round brackets.

(2) After declaring the declarator of overloaded constructor function, type the opening brace & start writing the function body.

(3) In function body, declare variable as per the variables in destination class data members, make necessary calculation and then write return statement.

Page 73: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 73 By V. D. Gokhale

ASTROMEDICOMP

(4) Writing return statement, starts with the word return, then again the “destination class name” then opening round bracket, then essential returnable answer variable names, if more than one then separate them by commas, and finally closing round bracket & semicolon. [Here too, you are writing destination class name, means you are writing constructor function of destination class.]

(5) At the end of operator overloading function, type closing brace.

** In Destination Class In source class, while writing operator overloading function, we write the destination class name twice. Once, after the word “operator” with empty brackets following and 2nd after word “return” with pairs of brackets enclosing the variable names.

This shows that there should be two constructor functions in the destination class, one with no parameters and other with parameters equal to the number of data items in the destination class.

These 2 constructor functions must be defined in destination class. (1) No return type – space – destination class name()

{ initialize destination class data members to zero } (2) No return type – space – destination class name( variable list )

{ data members = respective variable list } ** Above things can be cleared by one example Suppose we want to convert polar co-ordinates to rectangular co-ordinates. Polar co-ordinates are “radius & angle” while rectangular co-ordinates are “X-co-ordinate & Y-co-ordinate”. This can be done by 2 equations… x = radius * cos(angle) y = radius * sin(angle) Now when we declare 2 classes “rec” & “polar” and if we declare objects of them as “rec” & “pol” respectively, then the polar co-ordinates we want to get converted into rectangular co-ordinates, just by saying rec = pol. # include <iostream.h> # include <math.h> for sin, cos functions. class rec { private : double xco; double yco; public : rec() { xco = 0.0; constructor with

Page 74: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 74 By V. D. Gokhale

ASTROMEDICOMP

yco = 0.0; no parameters } rec(double x, double y) { xco = x; Constructor with 2 parameters, because class has 2 members. yco = y; In this constructor, data members are equated with } respective parameters void display() { cout << “X CO-ORDINATE = “ << xco << “&” << “\n”; cout << “Y CO-ORDINATE = “ << yco << “\n”; } }; class polar { private : double radius; double angle; public : operator rec() overloading constructor of destination class with no parameters.

{ double x; declaration of variables same as the number double y; of data members in destination class. x = radius * cos(angle); y = radius * sin(angle); return rec(x , y); returning variables to 2nd constructor of } destination class with parameters

void getdata() { cout << “ENTER RADIUS : “<< “\n”; cin >> readius; cout << “ENTER ANGLE : “ << “\n”; cin >> angle; }

void showdata() { cout << “Radius = “ << radius << “&” << “\n”; cout << “Angle = “ << angle << “\n”; } };

Page 75: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 75 By V. D. Gokhale

ASTROMEDICOMP

void main() { rec rec; object with same name, is nothing but

the call to constructor, with parameters polar pol; pol.getdata() this will get radius & angle from user rec = pol; Now just using “=” operator, polar co-ordinates will get converted into rectangular co-ordinates pol.display(); will display polar co-ordinates as ENTERED rec.display(); will display conversion of polar to rectangular } co-ordinates, in X & Y co-ordinate form. In this program, [Source Class] (1) We declare a class “rec” for rectangular co-ordinates having xco & yco data items of “double” type. (2) Then we designed two constructor functions

a) One with no parameters, in which xco & yco are initialized to zero. b) Other with 2 parameters x & y, which are assigned to xco & yco in this

function. (3) Then we declare a display function which will display the X co-ordinate & Y-co- ordinate [Destination Class] (1) We declare a 2nd class of “polar” name, for polar co-ordinates, in which there are 2 data items “radius” & “angle” of double type. (2) Then we write an operator overloading function in which we overload “rec” constructor function by operator keyword. In the function body, we declare 2 different “double” variables for polar co-ordinates and using necessary equations we find out values of those 2 variables and pass them to “rec()” constructor function by return statement. (3) In this class we also define a function “getdata() to get “radius” & “angle” from the user. (4) Here also we define a another function display, to display user entered “radius & angle”. (1) In main we declare an object “rec” of “rec” class. We just mentioned “rec” thus this is a call to first constructor function with no parameters, in “rec” class. (2) Then we declare another object “pol” of “polaer” class type. (3) By “pol.getdata()” function we receive radius & angle from the user. (4) Then we give a statement “rec=pol” means here “rec” becomes destination object

Page 76: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 76 By V. D. Gokhale

ASTROMEDICOMP

in which values of “pol” object are to be assigned. Thus “pol” becomes source object. When compiler enters in main(), it comes across first constructor function of “rec” type and thus initializes xco & yco to zero. Then by “pol.getdata()” function it receives radius & angle from the user. When it comes across rec=pol, then first it finds that assignment is not between objects of same class, but it is between the objects of 2 different classes. As “pol” is the source class, it enters in it, and searches for such a function which is able to convert the radius & angle of “pol” to xco & yco of “rec”. When it finds another overloading function of “rec” type, it enters in that function converts radius & angle to x & y and then enters in return statement. The return statement rec(x,y) has the name of other “rec” type constructor function which has 2 parameters. Thus by this return statement, compiler jumps to class “rec”, in the 2nd constructor function and assigns values of x & y to xco & yco respectively. Now by pol.display() function it displays entered values of radius & angle as they are. AND by rec.display() finction it displays xco & yco which are converted values of radius & angle. THE WHOLE THIING DESCRIBED ABOVE CAN BE DONE BY ANOTHER WAY, WHICH IS MORE SIMPLE. (1) Declare the Source & Destination classes as they are, by any way. Means 1st source class & then destination class OR 1st destination class & then source class. (2) The problem is, how the destination class will access that data members of source class? To solve this, count the data members of source class and declare those many functions with any names but each should return one data item at a time. As functions are usually “public” main can access them. (3) In destination class, declare one constructor (same name having function) having parameter object of source class. In the function body use the functions in the source class with parameterized object and get the data members of source class by this way. Do necessary conversions and find out data items of destination class. Close the function. (4) main() as it is… # include <iostream.h> class polar { private : double radius; double angle; public :

Page 77: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 77 By V. D. Gokhale

ASTROMEDICOMP

void getdata() { cout << “ENTER RADIUS : ” << “\n”; cin >> radius; cout << “ENTER ANGLE : “ << “\n”; cin >> angle; }

void display() {

cout << “RADIUS = “<< radius << “\n”; cout << “ANGLE = “ << angle << “\n”;

} double showrad() function which will return radius { return( radius ); } function which is public double showang() function which will return angle { return( angle ); } function which is public }; class rec { private : double xco; double yco; public : void display()

{ cout << “X CO-ORDINATE = “ << xco << “\n”; cout << “Y CO-ORDINATE = “ << yco << “\n”; } rec (polar p) Constructor function, with object of polar class, as its { parameter

double r; double a; r = p.showrad(); By these 2 functions, class rec can access a = p.showang(); the private data members of class polar xco = r * cos(a); member data conversion yco = r * sin(a); for polar to rec

} }; void main() { rec rec; polar pol;

Page 78: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 78 By V. D. Gokhale

ASTROMEDICOMP

pol.getdata(); rec = pol; pol.display(); rec.display(); }

* After classes, Inheritance is the remaining most important & powerful future of Object Oriented Programming. Inheritance is the process of creating such a new class from a class, that the new class will inherit all the capabilities of the original class, besides its independent capabilities. Means suppose there is a class A & we declare another class B, which is child of parent of A. Then the child class B has its own properties including all the properties of A. Here the parent class is known as BASE class while the child class is known as DERIVED class. Thus the derived class inherits all capabilities of base class, and also can add refinements in it, maintaining the base class unchanged. The most important advantage is that it permits code reducibility. Eg. # include <iostream.h> class vijay BASE CLASS [Parent] { protected : special attention word int lon, lat; public : void getdata()

{ cout << “ENTER LONGITUDE : “ << “\n”; cin >> lon; cout << “ENTER LATITUDE : “ << “\n”; cin >> lat; }

void showdata() {

cout << “LONGITUDE = “ << lon << “\n”; cout << “LATITUDE = “ << lat << ”\n”;

} }; class mithu : public vijay DERIVED CLASS [CHILD]

Page 79: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 79 By V. D. Gokhale

ASTROMEDICOMP

{ public : void showsum()

{ cout << “SUM OF LONGITUDE & LATITUDE = “ << “lon + lat << “\n”; } (derived class can access data members of base class,

}; because data members of base class are protected.) void main() { mithu m; object of derived class. m.getdata(); derived class object can access base class member function. m.showdata(); derived class object can access base class member function. m.showsum(); derived class using its own member function as usual. } ☺ How to declare the derived class? (1) First declare & define the base class, as usual. (2) If data items of base class are supposed to be used by derived class, then

declare such data items with keyword “protected :” in base class. (3) On the next line of closing brace of base class…

first type the word class then type the derived class name colon then one of the keyword private / public / protected [usually public] at the last, the base class name, and then usual class body.

Syntax :- class <derived class name> : <private/public/protected> <base class name> { class body. };

* NOTE Derived class name can refer to data & functions of base class, but base class has no access to data & functions of derived class. * In main(), there is object m of derived class “mithu”, then by m.getdata() a function is called. When a member function in the base class can used by objects of desired class, then the property is called as “ACCESSIBILITY”. Here getdata() is a member function of base class “vijay”, which is used by object “m” which is of derived class “mithu”. When compiler sees m.getdata() statement, first it looks for getdata() member function in the class whose object is “m”. Here “m” is the object of class “mithu”.

Page 80: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 80 By V. D. Gokhale

ASTROMEDICOMP

Thus compiler looks for function in class “mithu”. But this function is not available in class “mithu”. Hence compiler then searches for relation of class mithu with anyone. When it sees the statement class mithu : public vijay, it realizes that mithu is a derived class from base class “vijay”. Hence it enters in base class “vijay” and searches for getdata() function and it finds, and then executes it. [if not found, compiler will give error.] The above rule is true for Constructor, Destructor, and Operator overloading functions too. ☺ The “Protected” access specifier We know that, when data members of a class are private, they can be accessed only by member functions of that class or by nonmember friend functions.

Thus if data of base class made “private” as usual, then derived class member functions can not access that data, and the purpose of “inheritance” will get lost.

If data of base class is made “public”, then not only derived class, but all other classes, functions can use that data and the purpose of “data binding” will get lost.

Hence there should be such a way that, the private data of base class should be available to derived class and it should be accessible only to these 2 classes and their member functions and not to all. To serve this purpose the data of the base class is made “protected”. In above example lon & lat integers data items are made protected, hence they can be accessible to base and derived classes and not to anyone else. ACCESS SPECIFIER

ACCESSIBILTY FROM OWN CLASS

ACCESSIBILITY FROM DERIVED CLASS

ACCESSIBILTY FROM OBJECTS OUTSIDE CLASS

public Yes Yes Yes protected Yes Yes No private Yes No No Thus in general, when a class uses an access specifier “protected”, then it is sure, that this class will work as BASE CLASS some where else in the program.

• NOTE In inheritance, the base class remains unchanged means in above program, if we declare an object “v” of class “vijay”, then v.getdata() & v.showdata() are perfectly legal statements. But v.showsum() will be illegal statement, because showsum() function is not the member function of “vijay” (base class) but the member function of “mithu” (derived class) and as a rule base class objects can’t access derived class members, though they are public.

☺ Use of Access Specifier With The Name Of Base Class While declaring derived class, we follow the following syntax sequence…

1> The keyword class 2> Then a space 3> Then user defined name of derived class

Page 81: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 81 By V. D. Gokhale

ASTROMEDICOMP

4> Then colon 5> Then base class access specifier (private / public / protected) 6> Then again a space 7> Then user defined base class name 8> Usual class body This syntax tells the compiler that which is the derived class and from which base

class it is derived. Here we use private/public/protected access specifier with the name of base class.

Usually access specifier used is “public”. But we also can use private or protected access specifier.

When to use private or public or protected access specifier with the name of base class? (1) In the previous example, we used “public” access specifier with the base class “vijay”.

Public access specifier with the base class name causes… a> All public members of base class becomes public to derived class too.

In the example, getdata() & showdata() are “public” member function of class “vijay”. Now they become “public” to class “mithu” too and member functions of “mithu” can access them well. b> All protected members of base class remains protected for derived class too. In the example, lon & lat are protected data members of class “vijay”, which remains protected for class “mithu” and member functions of “mithu” can access lon & lat but with garbage values. c> All private class members of base class, remains “private” for derived class and derived class member functions can not access them. [NOTE Private data members of base class can’t be accessed in derived class, but object of derived class can access them via functions of base class.] (2) When Base Class is Inherited with “private” class specifier, then … All private, public members of base class becomes private members to derived class means, it in above example if we declare as… class mithu : private vijay Then a> lon & lat are protected in “vijay”, they get garbage values in “mithu”

b> though getdata() & showdata() are public in “vijay” they become private to mithu.

Hence member functions of “mithu”, like showsum() can access lon, lat members. [NOTE Neither derived class, nor object of derived class (though functions of base class) can access any member of base class, both data & functions.] (3) When Base Class is Inherited with “protected” access specifier, then…

Page 82: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 82 By V. D. Gokhale

ASTROMEDICOMP

All private, public & protected members of base class become protected in derived class too. Means, in above example, if we declare as… class mithu : private vijay Then a> protected lon & lat becomes protected in “vijay” get garbage values in “mithu” b> though getdata() & showdata() are public in “vijay”, they become protected in “mithu”. Thus “mithu” class member functions can access lon & lat in its body, but with garbage values. ☺ Multiple Inheritance One class can be a derived class from more than one base classes. Means, suppose there are 2 classes “class A” and “class B”. Then “class C” may be such a class which inherits both the capabilities of “class A” & “class B”. The declaration of derived class “c” is like… class C :public A, public B { class body }; Thus the syntax of multiple inheritance is…

a> class b> derived class name c> colon d> access specifier of first base class e> name of first base class f> comma g> access specifier of 2nd base class h> name of 2nd base class

: so on :

i> class body ☺ How to call base class members in derived class :-

First of all members which we want to use in derived class should made of appropriate access specifier.

a) data members of base class can be used directly in the derived class just by mentioning their names wherever necessary, with name :: member

b) But member functions of base class, when we want to use in derived class, then scope resolution operator (::) is used as…

Page 83: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 83 By V. D. Gokhale

ASTROMEDICOMP

base class name :: base class member function name; Eg. Class A { protected : int x, y, z; public : void getdata()

{ cout << “ENTER VALUE OF X :” << “\n”; cin >> x; cout << “ENTER VALUE OF Y :” << “\n”; cin >> y; }

void multiplication() {

z = x * y; } }; class B : public A { A :: multiplication(); void showdata()

{ cout << “MULTIPLICATION OF “ << x << “ & ” << y << ” = “ << z << “\n”; }

}; void main() { B p; object of derived class p.getdata(); member function of base class p.showdata(); member function of itself } Here as derived class B can directly access x, y, z there is no need of calling “multiplication()” function in derived class. But this is just a demonstration. ☺Can we use same function names, both in BASE & DERIVED CLASSES:- Answer is “YES”. Eg.

Page 84: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 84 By V. D. Gokhale

ASTROMEDICOMP

class vijay { protected : int lon,lat; public : void getdata()

{ cout << “ENTER LONGITUDE : “ << “\n”; cin >> lon; cout << “ENTER LATITUDE : “ << “\n”; cin >> lat; }

void showdata() { cout << “LONGITUDE = “ << lon << “\n”; cout << “LATITUDE = “ << lat << “\n”; }

}; class mithu : public vijay { private : int sm; public : void getdata()

{ cout << “ENTER STANDARD MERIDIAN : “ << “\n”; cin >> sm; }

void showdata()

{ cout << “STANDARD MERIDIAN = “ << sm << “\n”; }

}; void main() { vijay v; mithu m; v.getdata(); v.showdata(); m.getdata();

Page 85: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 85 By V. D. Gokhale

ASTROMEDICOMP

m.showdata(); } * In this example we use getdata() & showdata() same function names in both base & derived classes, but with different codes.

Now for the case of base class object “v”, there is no question “As base class does not know anything about derived class”, statements v.getdata() & v.showdata() will obviously execute getdata & showdata in member functions in base class.

But question will arise about derived class object “m”. When we say m.getdata() & m.showdata() 2 situations may take place…

(1) whether to execute getdata() & showdata() of member functions of derived class “mithu”?

(2) Or as derived class has access to getdata() & showdata() of “vijay”, m.getdata() & m.showdata() may execute these functions from “vijay”.

How compiler will decide which functions are to be used? Note that compiler will execute getdata() & showdata() of derived class & not of

base class. * Thus when same function names [with either same or different function codes] are present in both base & derived classes, then objects of derived class will execute functions of their own when they are called. Thus objects of derived class will not execute same functions of base class. This is said that “Derived Class Function Overrides The Base Class Function.” Because we are referring these “same name functions” by object of derived class. ☺ CONSTRUCTORS AND DESTRUCTORS IN INHERITANCE It is possible that both base class * derived class contain constructor and/or destructor as requirement. However it is important to know the order in which the constructor & destructor gets executed. # include <iostream.h> class base { public : base() constructor { cout << “Constructing Base.” << “\n”; } ~base() destructor { cout << “Destructing Base.” << “\n”; } }; class derived : public base { public :

Page 86: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 86 By V. D. Gokhale

ASTROMEDICOMP

derived() constructor { cout << “Constructing Derived.” << “\n”; } ~derived() destructor { cout << “Destructing Derived. “ << “\n”; } }; void main() { derived ob; object “ob” of derived class “derived” of base class “base”. } When executed, this program gives following output… Constructing Base.

Constructing Derived. Destructing Derived. Destructing Base. This output shows that…

(1) First base constructor gets executed and then derived class constructor gets executed. While…

(2) First derived class destructor gets executed and the base class destructor gets executed.

These 2 rules can be generalized as… When an object of a derived class is created, ( object “ob” of derived class “derived” in this example) if the base class contains a constructor, it will be called first ( base() in this example) followed by derived class constructor (derived() in this example). While when an object of a derived class is destroyed then the destructor of derived class is called first ( ~derived() in this example), followed by destructor of base class ( ~base() in this example). Thus constructors are executed in order of their derivation, while destructors are executed in reverse order of their derivatin. This happens because… Base class has no knowledge of derived class, but derived class has knowledge about base class, according to the base class’s access specifier in derived class declaration. * The same above rules are applied to “multiple inheritance” means when one base class has its derived class and this derived class is again base class for its derived class. * Also the same above rules are applied to “multiple base class” means when one derived class is derived from more than one base class. Only here the sequence of constructor/destructor execution is from left to right. Eg. class derived : public base1, public base2 { :

Page 87: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 87 By V. D. Gokhale

ASTROMEDICOMP

}; Suppose base classes base1 & base2 are having constructor and destructor and also derived class is having constructor & destructor then…

First constructor of base1 will get executed. ( from left to right). Then constructor of base2 will get executed. Then constructor of “derived” will get executed.

Also -> destructor in reverse order. First destructor of “derived” will get executed. Then destructor of base2 will get executed. Finally destructor of base1 will get executed.

☺ How object of a derived class can pass parameters to the constructor of base class?

If only derived class constructor is having one or more parameters, then as usual they can be passed directly to the respective constructor function in the derived class.

But problem arise when… 1) Either derived class constructor is having no parameter, but it is calling base

class constructor (which has parameter or not). 2) Or derived class constructor with its own parameter, and calling base class

constructor (which has parameter or not). Means there is a problem of passing parameter to base class constructor, via

derived class constructor… To solve this problem a general syntax should be used in derived class body as… <name of derived class constructor> (parameter of its own) : <name of base class constructor> (parameter of its own) {

constructor’s body; }

Eg. # include <iostream.h> class base { protected : int i; public c : base(int x)

{ i = x; cout << “Constructing Base.” << “\n”; }

Page 88: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 88 By V. D. Gokhale

ASTROMEDICOMP

}; class derived { int j; public : derived : derived(int x, int y) : base(y)

{ j = x; cout << “Constructing Derived.” << “\n”; }

void show() { cout << i << “ “ << j << “\n”; }

}; void main() { derived ob(3,4); ob.show(); }

In this example… Base class “base” has one one-argument constructor means having one parameter

as x. In derived class we want to create such a constructor which has its own parameter

as well as it can pass parameter to base class constructor too. * One + one = two, hence we should declare such a constructor which should have 2 parameters x & y. Out of which x will be used by derived class constructor itself and y will be passed to base constructor via “ : base(y)” piece of declaration.

In main() we declare object “ob” of derived class with 2 parameters 3 & 4. Out of which 3 will be used by derived constructor & 4 will be passed to base constructor.

Output will be 4 3 why? Because as per the rule of previous topic, base’s constructor called first and then derived’s constructor is called. Hence “base(y)” is called first, answering i=4, and then “derived(x)” will be called answering y=3. The “void show()” function will display this answer. In general when object of a derived class is created and when derived class contains a constructor, which is in turn going to call a constructor from base class and both of those constructors may or may not have parameters, then…

(1) Declare base class as usual, with its constructor (which is with or without parameter).

(2) In derived class, if you want to create such a constructor, which is going to call constructor from base…

Page 89: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 89 By V. D. Gokhale

ASTROMEDICOMP

a) type derived class constructor name (obviously the class name). b) open round bracket. c) if this derived class constructor and base class constructor, both do

not have any parameters then “closing round bracket”. -> case 1 If only derived class constructor has parameter then mention it, if

more than one, then separate by commas. -> case 2 If only base class constructor has parameter, then mention it, if more

than one then, separate by commas. -> case 3 If both derived class & base class constructor contain parameter, then

first mention derived class constructor’s parameters & then base class constructor’s parameters, each separated by comma. -> case 4

d) closing round bracket. e) colon. f) base class constructor name (obviously base class name). g) open round bracket h) if no parameters, then closing round bracket

if parameters are there, then mention them as in C. (but only of base’s constructor and not of derived’s constructor)

i) opening brace - - - constructor’s body - - - closing brace ☺ Cases Suppose “vijay” is a base class & “mithu” is a derived class &

mithu’s constructor is calling vijay’s constructor… Case 1 “vijay” has a constructor with no parameters. “mithu” has a constructor with no parameters then…. mithu() : vijay() * if derived class constructor is calling base { class constructor only, means derived class

constructor’s body constructor has no “constructor body”, then }; too empty braces must be given as { }

Case 2 “vijay” has a constructor with no parameter, “mithu” has a constructor with one parameter then… mithu (int x) : vijay() { i=x; constructor body etc; } Case 3 “vijay” has a constructor with one parameter, “mithu” has a constructor with no parameter, then… mithu(int x) : vijay(x) { constructor body;

Page 90: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 90 By V. D. Gokhale

ASTROMEDICOMP

( though “x” is not for mithu but for vijay, “mithu” can use x too) } Case 4 (a) Both “vijay” & “mithu” contain constructor with one parameter each, then… mithu(int x, int y) : vijay(y) { constructor body; (though y is given for vijay, mithu can use both

its own “x” & vijay’s “y” in its construction body) }

(b) Both “vijay” & “mithu” class constructor are using multiple parameters… Say “mithu” is using 2 parameters & vijay is using 3 then… mithu (int p, int q, int r, int s, int t) : vijay(r,s,t) { (though r, s, t are of vijay, “mithu” can use its own p, q

with vijay’s r, s, t) construction body

} In general derived class constructor must declare both the parameter(s) which are used b itself and also of required by base class. If derived class constructor has “no parameters & no function body”, then too empty pairs of braces must be typed. Eg. mithu(char aa[ ], char bb[ ], float x, float y, double p, int q) : vijay(x, y), rama(p, q) { construction body, using its own aa, bb and/or all mentioned.

} Here “mithu” is a constructor of derived class “mithu” from 2 base classes

“vijay” & “rama”. Now suppose “mithu” constructor wants to call constructors in vijay & rama at

a time and if all “mithu”, “vijay” & “rama” are having 2 parameters each then… “mithu” function constructor is declared with 6 parameters aa, bb for itself x & y for “vijay”, which are passed to “vijay” p & q for “rama”, which are passed to “rama”

NOTE While writing all parameter list with the derived constructor name, the parameters are written with their respective data types as int, float, double & char. While when we pass them to constructors of base, the names of base constructors are just followed by names of parameters, and not their types.

Page 91: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 91 By V. D. Gokhale

ASTROMEDICOMP

* Suppose there is global int i, at the same time there is local int i, then the local int i is accessed by its name i and global int i is accessed as ::I ** Granting Access During previous topics we have seen that, the derived class, in its body, can call members of base class by the syntax… base class name :: base class members; Thus using scope resolution operator, we can use base class data & functions directly in the body of derived class. Eg. -> Suppose base class “vijay” contains one data item as “int i” and 2 functions “geti()” & “showi()” AND if we want to use them in “mithu” derived class body too, then we can do it by… Class mithu : public vijay { public : vijay :: i; no need of mentioning data type. vijay :: geti(); no need of mentioning a) return type vijay :: showi(); b) pair of round brackets c) parameters } Notes (1) When calling base class data members in derived class body, there is no need of mentioning data type with scope resolution operator. Means “vijay :: int i;” Here the word “int” is not necessary. C++ can automatically identify the data type. (2) When calling base class function members, there is no need of mentioning a) return type, b) pair of round brackets. Means… vijay :: void geti() Here “void” & “( )” are vijay :: void showi() unnecessary.

• But the most important is that ……. • When a base class is inherited using the access specifier “private” and not “public”… Eg.-> class mithu : private vijay

Then all private, protected and public members of base class becomes “private” to derived class. Thus derived class body has access to them, but derived class objects, declared in main( ), do not have access to them. If, in certain circumstances, we want to restore the original access of members of base class in the body of derived class, means, suppose………

class vijay { private: int j;

Page 92: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 92 By V. D. Gokhale

ASTROMEDICOMP

public: void getj()

{ cout << ”ENTER AN INTEGER NUMBER” << ”\n”; cin >> j; }

void showj() {

cout< “YOU ENTERED”<<j>>”\n”; }

}; Here in class vijay, getj() & showj() member functions are public.

class mithu : private vijay { public: (1) vijay :: getj; (2) vijay :: show (3) }; Now class “mithu” is derived from base class “vijay”. If base class vijay is

inherited by using access specifier “public”, then there should be no problem in using getj() & showj() in “mithu’s” body. But here base class “vijay” is inherited using access specifier “private”, which means j, getj() & showj() members of “vijay” private to class “mithu”. Now to restore original “public” access of getj() & showj() in “mithu”…

(1) First of all write the original access of required members in the derived class body. Means getj() & showj() have their original access “public” in “vijay”. Thus we have to write “public” in “mithu”.

(2) Then by using the scope resolution operator, call the required members. vijay :: getj; No need of return type (void) and no need of vijay :: showj; round brackets. Just name of member is enough.

(3) This declaration wil call getj() & showj() functions from “vijay”, though “vijay” is specified “private” to “mithu”. And as this declaration is done under the heading “public”, in “mithu”, now getj() & showj() can be accessed by “mithu” and as well by the objects of “mithu” in main.

NOTE While restoring access in the derived class, one thing should be kept in mind, that…

a) You can restore the original access (in above class) in derived class under appropriate access heading.

b) But you can not change the original status in derived class, with subject to base class. Especially you can not make “public” in derived class of a private member base class.

Page 93: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 93 By V. D. Gokhale

ASTROMEDICOMP

Both a & b are must when a base class is inherited by access “private”. Eg. # include < iostream.h > class base { private : int i; public : int j,k; void getijk()

{ cout << “ENTER THREE INTEGER NUMBERS :” << “\n”; cin >> i >> j >> k; }

void showijk() {

cout << “YOU ENTERED :” << i << j << k << “\n”; } }; class derived : private base { public : base :: j; base :: getijk; base :: showijk; base :: i; Error }; void main() { derived ob; ob.i = 10; Error ob.j = 20; ob.k = 30; Error ob.getijk(); ob.showijk(); }

In this example class “derived” is derived from class “base” and the class “base” is inherited by access specifier “private”. Thus all members of class “base” viz_ i, j, k, getijk() & showijk() become “private” to class “derived”, though j, k, getijk() & showijk() are “public” members.

Page 94: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 94 By V. D. Gokhale

ASTROMEDICOMP

Now suppose we want to restore the original base class of j, getijk() & showijk() as “public” in class derived. To do this, in class “derived”, first we give heading access as “public” and then using scope resolution operator we restore the original access of members .

• By base :: j; statement, “public” j gets restored as public in derived class too. • This is true for remaining both base :: getijk() & base :: showijk(). But by the statement base :: i; under the heading “public”, we are trying to change

“private” member (in base class) to “public” (in derived class) which will give error. Obviously ob.i = 10; will also give error, because “ob” is a derived class object and

thus can’t access private members of base class. ob.j = 20; is perfectly correct statement, because though “base” class is inherited

as “private” to “derived” class, we restore access “public” of j as it is in derived class. But we don’t restore access of k, hence ob.k = 30; statement will give error. We restore “public” access of getijk() & showijk() functions in “derived class” with

respect to “base class”. ob.getijk(); though both these functions contain “i”, they will get perfectly ob.showijk(); executed, getting values of I, j & k and then printing them. ** Virtual Base Classes :- Consider the following example… # include < iostream.h > class base { public : int i; }; class derived1 : public base { public : int j; }; class derived2 : public base { public : int k; }; class derived3 : public derived1, public derived2 { public : int sum; };

Page 95: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 95 By V. D. Gokhale

ASTROMEDICOMP

void main() { derived3 ob; ob.i = 10; ambiguous due to “i”. ob.j = 20; ob.k = 30; ob.sum = ob.i + ob.j + ob.k; ambiguous due to “i”. cout << ob.i << “\n”; ambiguous due to “i”. cout << ob.j << “\n”; cout << ob.k << “\n”; cout << ob.sum << “\n”; Incorrect Sum. } This program will not get compiled due to errors. * In this program there is a class “base” with one “public” integer variable “i”. Class derived1 & derived2 are derived classes from class “base” with “public” access specifier. Both classes contain “public” integer variable as “j” & “k” respectively. Class derived3 is a derived class of both derived1 & derived2 with “public” access specifier each. Now “derived1” contains one copy of class “base” [as it is derived from “base”] and “derived2” also contains one copy of class “base” [as it is also derived from “base”]. Obviously “derived3” will contain 2 copies of “base” as it is derived from both “derived1” and “derived2”. Thus “ob.i” related all statements in main() will be ambiguous and error causing. Because ob is an object of derived3. When we say ob.i = 10…

compiler enters in that class, whose object is “ob”. Here compiler will enter in “derived3” class and search for “i”.

But there is no declaration concerned with “i” in “derived3”, thus it will enter that class, from which “derived3” is inherited.

If derived3 was inherited with either one of the “derived1” or “derived2”, then there would be no problem. But as “derived3” is inherited from both “derived1” & “derived2”, compiler can not refer “i” to either “derived1” or “derived2”. There are 2 solutions to this problem. Sol.n 1 First make sure, from which class, you want to refer the derived variable or function. After this use scope resolution operator and call the respective member with respective class. Suppose here we want “i” from “derived1”, then in main() we can say… ob.derived1 :: i = 0; [Here “i” from “ob.i” is replaced by “derived1 :: i”]

Page 96: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 96 By V. D. Gokhale

ASTROMEDICOMP

ob.sum = ob.derived :: i + ob.j + ob.k; cout << ob.derived :: i; All the 3 ambiguous statements can be corrected as above. Sol.n 2 Though solution1 removes ambiguity and gives correct answer, two copies of class “base” remain in “derived3” as it is. If we don’t want this solution [means suppose though “derived3” is derived from “derived1” & “derived2” each of which contains one copy of class “base”, but we want only one copy to get introduced in “derived3”, then…], the answer is to use VIRTUAL BASE CLASS. When object of a class “C” is declared and class “C” is derived from multiple base classes say class “A” & class “B” and both class “A” & class “B” are derived from a single base class “X”, then to avoid multiple copies of “X” in the objects of “C” [one from A & second from B] the common class “X” should be inherited as “virtual”, which can be done by typing the word virtual before the base class name, when declaring the derived class. class X {

: }; class A : virtual public X derived classes of a common base class, should be { inherited by keyword “virtual” having common base

: class. }; Note Though the keyword “virtual” is used, don’t class B : virtual public X forget to write access specifier too. {

: }; class C : public A, public B {

: };

• The Erroneous example now can be rewritten as … # include <iostream.h> class base { public : int i; }; class derived1 : virtual public base { public :

Page 97: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 97 By V. D. Gokhale

ASTROMEDICOMP

int j; }; class derived2 : virtual public base { public : int k; }; class derived3 : public drived1, public derived2 { public : int sum; }; void main() { derived3 ob; ob.i = 10; now perfectly correct & unambiguous ob.j = 20; ob.k = 30; ob.sum = ob.i + ob.j + ob.k; now perfectly correct cout << ob.i << “\n”; now perfectly correct cout << ob.j << “\n”; cout << ob.k << “\n”; cout << ob.sum << “\n”; Correct Sum. } Now object of “derived3” class “ob” will contain only one copy of class “base” as it is inherited as “virtual”. ** Class Hierarchies :- In using inheritance, situation may occur, as we declare a base class and inherit it with many derived classes, then in main() we derived objects of derived classes but not a single object of base class, then the base class is known as Abstract Class. Eg. class X {

: }; class A : public X {

: }; class B : public X

Page 98: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 98 By V. D. Gokhale

ASTROMEDICOMP

{ :

}; void main() { A aa; Objects of derived classes A & B. But there is no object B bb; of “X”. Hence here “X” is called as “Abstract Class”. : }

• Containership : Classes Within Classes In inheritance, if class B is derived from class A, then we can say that “B is a kind of A”. This is because B has all the characters of A and in addition some of its own. For this reason, inheritance is sometimes called “kind of” relationship. There is another kind of relationship, called as “has a” relationship which is also known as “Containership”. In OOP, the “has a” or “containership” occurs when one object is contained in another. Eg. Suppose object of a class B is contained in class A… Class A { B b; class A contains object of class B [indirectly class A contains property of B] }; Class B {

: }; Thus we can say that inheritance & containership can serve similar purpose. Containership is useful when classes act like data types. Means object of one class can be used in another class just like we use variable in a class. But often “inheritance” is used, because it gives more clear conceptual framework.

POINTERS IN C++ ☺ In C++ pointers are mainly used for…

(1) Accessing array elements. (2) Passing arguments to a function, when the function needs to modify the

original arguments. (3) Passing arrays & strings to functions. (4) Obtaining memory from system. (5) Creating data structures such as linked list.

Page 99: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 99 By V. D. Gokhale

ASTROMEDICOMP

☺ Ideas About Pointers Common In Both C & C++ (1) Every byte in the computer’s memory has a address. Addresses are numbers, just like numbers for houses on a street. In memory, these numbers start from 0 and then 1, 2, 3 and so on. Thus if we have 640K of total memory, then the highest address is 655,359. For 1Mb memory, the highest address is 1,048,575 and so on. When we load our program in the computer’s memory, then the program occupies some address range, which means that every variable & function in our program starts at a particular address. (2) The “Address Of” operator (&) We can find out the address of a variable or a function by using an Operator “&”, which is known as “Address Of” operator. Eg. Suppose we declare an integer variable “var” and assign value 11 to it, then…

int var = 1; cout << “Value Of var = “ << var << “\n”; cout << “Address of var = “ << &var << “\n”;

Here first “cout” statement will print 11 and 2nd “cout” statement will print something like 0x8f4ffff4 which will be the address of “var” variable. The address may be different on different computers, or even this address yields during first execution, next time it may be something different than previous.

Note Address & Value are totally different entities. The numbers 0x8f4ffff4 a hexadecimal number, because “<<” operator always gives address in hexadecimal notation. Suppose we have a following example

void main() { int var1 = 11; int var2 = 12; int var3 = 13; cout << &var1 << “\n”; prints address of var1 cout << &var2 << “\n”; prints address of var2 cout << &var3 << “\n”; prints address of var3

} The 3 “cout” statements will give something like… 0x8f4ffff4 Here these addresses are not important 0x8f4ffff2 because they may be different at next 0x8f4ffff0 time or different computers The important things are…

“<<” operator prints addresses in hexadecimal notation, starting with ox prefix. All the three addresses are not same, which indicates that, in computer’s memory

every variable or function starts at a unique address, which is never identical with some one else’s address.

Page 100: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 100 By V. D. Gokhale

ASTROMEDICOMP

If we observe the 3 addresses, especially their last digits, then we can see that there is difference of 2 in each address. This is because, integer occupies 2 bytes in memory, and variables or functions are kept adjacent to each other, according to their order of declaration. Thus….

a> If two integers are declared one after the other, then the difference between their addresses is of 2, because integers occupying 2 bytes in memory. Eg. :- ox8f4ffff4, ox8f4ffff2

b> If two floating variables are declared one after the other, then the difference between their addresses will be of 4, because floating numbers occupy 4 bytes in memory. Eg. :- 0x8f4ffff4, 0x8f4ffff0.

c> If two double variables are declared one after the other, then the difference between their addresses will be of 8, because double variable occupy 8 bytes in memory. Eg. :- 0x8f4ffff8, ox8f4ffff0.

d> If two char variables are declared one after the other, then the difference between their addresses will be of 1, because char variable occupy 8 bytes in memory. Eg. :- 0x8f4ffff8, ox8f4ffff7.

Similarly long integer variables occupy 4 bytes, long double variables occupy 10 bytes in memory.

If we observe the 3 addresses on previous page, then we can see that addresses appear in descending order. This is because we declare all the 3 integer variables as automatic [Means after main(), locally]. These addresses will appear in ascending order, if we declare these variables external [Means before main(), globally].

In C++, do not confuse with “&” operator. Because it is used by 2 ways… a) When it is preceding a variable name (means before the variable name),

then it acts as “Address Of” operator. Eg. :- &var. b) When it is following a variable name (means after the variable name), then

it acts as “Reference Operator”. Eg. :- var &. (3) Pointer Variables By “Address Of -> &” operator we can print the address of a variable or function, but this is not all. To use these addresses powerfully, we need such a variable, which can hold these addresses. [Indirectly, we should be able to assign “&var” to some variable]. Such a variable which can hold the address, is known as Pointer Variable or simply Pointer. Such variable [as all other variables] must be declared before its use in the program. The syntax of pointer variable declaration is … data type * pointer variable name; Eg. (1) char* cptr; pointer to “char”.

Page 101: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 101 By V. D. Gokhale

ASTROMEDICOMP

(2) int* iptr; pointer to “int”. (3) float* fptr; pointer to “float”. (4) double* dptr pointer to “double”. Above examples are of pointers to C’s inbuilt data types. Suppose we have user defined data types such as struct vijay or class rama, then pointers to these user defined data types will be… (5) vijay* v1; pointer to “struct vijay”. (6) rama* r1; pointer to “class rama”. This should be noted that there are two ways to write “*” mark when declaring pointers (a) Near the data type Eg. int* var; (b) Near the pointer variable Eg. int *var; These 2 methods are identical to compiler, but for better readability and to know that which data type, pointer is pointing, the first approach is better. Means it is better to write * more near the data type rather than near the pointer variable name. After declaring pointer variable, we can assign any address to this variable. Eg. int var1 = 11; variable is given a value.

int* ptr; pointer variable is declared. ptr = &var1; address of variable is assigned to the pointer variable. (Note that “*” is a part of declaration. Means *ptr is not pointer variable. Pointer variable is “ptr” only.) Then question arises what *ptr means? The answer is *ptr is nothing but var1. In above example, we declared an integer variable “var1” and assign value 11 to it. Then we declare “pointer variable to int” as “ptr”. We assign address of var1 to ptr. Now to get the value of var1 we have 2 approaches… (1) Direct Approach We can get the value of var1, i.e. 11, just putting “var1” with “cout <<” statement as cout << var1; answer will be 11. (2) Indirect Approach We can use “value at a certain address” method. Means “certain address” is “pointer” and “value at” is “*”. Combining these 2 syntax we get “*ptr” and using this with “cout” statement we will get the same answer as… cout << *ptr; answer will be same, 11. same Now we know that “ptr” is nothing but “&var1” thus we also can write … cout << *(&var1);

Thus “*” means “value of the variable pointed to by” OR “value of the pointer at the given address”.

Thus “*” is also known as “Indirection Operator”, as it gives “value indirectly”.

Page 102: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 102 By V. D. Gokhale

ASTROMEDICOMP

And the method of “getting value indirectly” is known as “Indirect Addressing” or “Dereferencing the pointer”. *** We can explain “Direct” & “Indirect” approaches of getting variable value, by a simple example… Suppose I want to give a letter to my friend, then I can use 2 methods.. A> I can put the letter in an envelope and drop it in the house of my friend, through window. Hence this is Direct Approach. B> OR I can put the letter in mail box, so that postman can give this letter to my friend. Here I sent the letter indirectly (via postman) to my friend, hence this is Indirect Approach. * Now a question will arise, if direct method is simple and available, then why to use indirect method? [Means if we can access a variable value directly by its name, then why to use pointer?] The answer is, here we can use “variable name” directly, because we know the variable name. But there are many variables, name of which we don’t know, then to access values of such variables, we must use pointers. (4) Pointer to void In examples on previous 2-3 pages we have saw that when we want to assign an address of a variable to a pointer variable, we declare the pointer of same type as that of original variable. Means to assign “&var1” of “int var1”, we declare “ptr” pointer of “int” type, as int* ptr; [NOTE when we declare pointer to void and use this pointer multiple times, then at every use we must cast respective data type. Eg. Suppose void* ptr;

ptr = &ivar; and ivar is an integer, then in cout statement we have to cast “ptr” to int. cout << *(int *)ptr; ] Thus float num; int* p;

p = &num; this is illegal, because we are assigning addresses of float variable to integer pointer.

float num; float* p;

p = &num; Now this is legal, because now we are assigning “float” variable addresses to “float pointer”.

Page 103: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 103 By V. D. Gokhale

ASTROMEDICOMP

To avoid above silly mistakes, we can declare such a pointer variable which can be assigned to variable of any data type. This pointer variable is known as “pointer to void”, and it is defined as void* pointer variable name; Now above examples also can be written as… void main() { int var1 = 11; float num = 3.14; void* ptr; pointer to void ptr = &var1; assigned to address of “int” variable cout << *(int *)ptr; will give answer 11 ptr = &num; assigned to address of “float” variable cout << *(float *)ptr; will give answer 3.14 } In first “cout” we want to print “int” value. Hence *ptr is casted to *(int *)ptr. Similarly in next “cout” to print float value, *ptr is casted to *(float *)ptr. (5) Pointers and Arrays There is a close relation between pointers and arrays. If we declare an array of integer numbers as int array[5] = {31, 54, 77, 52, 93}; Then we can get the elements 31, 54, 77, 52 & 93 by 2 ways (a) Array indexing & (b) Pointers. (a) Accessing Array Elements Using Array Indexing # include <iostream.h> void main()

{ int array[5] = {31, 54, 77, 52, 93}; int i; for(i = 0; i < 5; i++)

{ cout << array[i] << “\n”; }

} Here we know that array[0] = 21, array[1] = 54 & so on. Thus we only need an

integer number which will first equal to 0 then 1, 2 and so on. When we use this number to get array elements, then this integer number is known as Index. Now using “for loop” where index number “i” gets value from o to 4, incremented by 1 each time up-till i<5, then array[i] will give all array elements. (b) Accessing Array Elements Using Pointer Notation # include <iostream.h> void main()

Page 104: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 104 By V. D. Gokhale

ASTROMEDICOMP

{ int array[5] = {31, 54, 77, 52, 93}; int i; for(i = 0; i < 5; i++)

{ cout << *(array+i) << “\n”; }

} If we observe above 2 programs we get that everything is same expect the “cout” statement. By index method array elements are accessed by array[i] expression, while by pointer method, same task is done by *(array+i) expression. This shows that both array[i] & *(array+i) are equal. And really they are equal. Now question arises how we can do it by pointer method?

• Observe carefully *(array+i) expression. We found two entities a) “*” indirection operator, which is used for “value at” b) (array+i) Here we can note that as “*” precedes “something”, that “something” must be

an address. So array+i must be an address. NOTE that Name of an array is the address of 0th element of that array and “&” is not necessary to indicate this array address. Therefore “array” which is name of an array is address of 0th element, i.e. of 31. Thus if we use “*array” in “cout”, then 31 will get printed. ( *array – means value at address “array”). Now *array is nothing but equal to *(array+0) which is equal to 31.

Similarly we can say that *(array+1) will be equal to 54, *(array+2) will be equal to 77 & *(array+4) will be equal to last element of array, i.e. 93.

Thus when we use *(array+i) expression in “for loop”, the index ”i” takes values from 0 to 4 [as we limited looping by I<5], every time incremented by 1 by above expression “i++”.

From above explanation we come to following conclusions 1) Name of the array is address of the 0th element of that array, known as Base

Address. 2) For the address of variables, we have to denote them by “&” mark before the

name of variable. But for array address, there is no need of “&” before the name of that array.

3) In a loop, having index “i”, which is correctly limited and incremented, the expression array-name[i] & *(array-name+i) work exactly equal.

4) Suppose address of an array is 0x8f4ffff4 [address of 0th element] then if we add index “i” to it then…

When i= 0 address will remain same.

Page 105: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 105 By V. D. Gokhale

ASTROMEDICOMP

When i = 1 Note that the address will not get changed from 0x8f4ffff4 to 0x8f4ffff5 but the address will get incremented by 2, because compiler knows that array is of “integers”.

This means that, if this array works of “float” then the original address of 0th element 0x8f4ffff4 would be changed to 0x8f4ffff8 because array is of “float” variables. When compiler increments address by respective bytes, the pointer points to the next location in the array and “*” operator gets value at that location. Thus…

5) When the address of an array is incremented or decremented by using pointer variable, then the pointer will point to next location of same data type.

6) Address itself can not be incremented or decremented itself. Means expression array++ or ++array in above example will produce error,

because address is constant. Then how to increment the address, the answer is…

a) first declare a pointer variable of that type. Eg. for int array[5] = {31, 54, 77, 52, 93} we declare int* ptr;

b) Assign the base address of that array (means array-name) to that pointer variable Eg. ptr = array; there is no need of “&”.

c) And then increment (++) or decrement (- -) that pointer variable, in a loop, as you wish. Eg, for(- - - - - -) { : ptr++; } Thus the above example, also can be displayed as… int* ptr; ptr = array; for(i = 0; i < 5; i++) { cout << *ptr << “\n”; no use of array or “i”. ptr++;

} ☺ Pointers And Functions There are 3 ways in C++, to pass arguments (parameters) to a function. (1) Passing by value (2) Passing by reference (3) Passing by pointer Out of these 3 ways, 2 are already seen before. Here we will see Passing Arguments (parameters) by Pointer. This is done as….

1) First declare the function prototype as usual, but using pointer in its round bracket pair. Eg. return type function name (data type *);

if more than one arguments are there, then separate by commas.

Page 106: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 106 By V. D. Gokhale

ASTROMEDICOMP

2) In the program body, pass the address of variable, to the function. i.e. function name (& variable name); OR variable name1 = function name(& variable name2); But if the argument is an array, then we know hat array-name itself is an address of that array. Hence no need of “&” operator here. i.e. function name (array name); no need of “&”.

3) While writing function declarator and the function body…. Return type function name (data type* variable name)

{ any user defined : use of the variable name along with “*” in function body : return (return variable) }

When we use pointer method for array, then in loop we can increment the pointer variable by ++ and so on. Thus… for(i=0; i<5; i++) { cout << *ptr; ptr++; } Above method is perfectly correct. We also do similar thing just by… for(i=0; i<5; i++) { cout << *ptr++; } “*ptr++” how do we know that, compiler will increment first and then get value of incremented address. Means the above expression can be executed as…. ( ) (1) first “*” will get operated, getting value of “*ptr” which will be then

incremented by “++”. ( ) (2) OR first “ptr” will get executed by incrementing pointer variable and then

getting value of the incremented address. Out of the 2 the second is correct. Here “++” is executed first and then “*” gets executed. Means right handed operator is executed before left handed operator. This property is known as “Right Associativity”. ☺ Sorting Of Array Elements Suppose an array of 10 integer numbers is given and we are asked to sort them in ascending order, means lowest first and greatest last.

Page 107: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 107 By V. D. Gokhale

ASTROMEDICOMP

In this sorting we are going to change the present position of numbers in the array. Thus we are going to modify original values, hence we must use pointers here. Procedure Suppose array is of 10 integer numbers. To sort the elements, 1st number is compared with remaining 9 numbers, if it is least of all, it will be kept as it is, but someone else is least, then that number will take first position, and original first will take the previous number’s position. This process is called as “swapping”. After fixing first number, now some process is done with 2nd number and remaining 8 numbers. After fixing 2nd, third is fixed and so on. This searching method is known as “Bubble Sort”. In the program we need 2 loops, the outer loop is for original numbers and inner loop is for comparing numbers.

Bubble Sort # include <iostream.h> void main() { const int MAX=10; constant array size. int array[MAX] = {37,84,62,91,11,65,57,28,19,49}; Array of 10 integer numbers void sort(int*, int); declaration of prototype of a function having 2 arguments, one is for “array address” & 2nd is for “array size” sort (array, MAX); the “sort” function is called by passing “array name as array address” and “array size” for(i=0; i<MAX; ++i) loop to get sorted array {

cout << array[i] << “\n”; } } void sort(int* arr, int num) “sort” function declarator { void swap(int*, int*); “swap” is a function having 2 pointer parameters int j, k; for(j=0; j<num-1; ++j) outer loop

{ for(k=j+1; k<num; ++k) inner loop { swap(arr+j, arr+k); 1st argument -> original num } 2nd argument -> compared with }

} void swap(int* ptr1, int* ptr2) “swap” function declarator { int temp;

Page 108: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 108 By V. D. Gokhale

ASTROMEDICOMP

if(*ptr1 > *ptr2) value of 1st is > value of 2nd { temp = *ptr1; “swapping” 1st value is given to temp. *ptr1 = *ptr2; 2nd value is assigned to first. *ptr2 = temp; & finally temp is assigned to 2nd. }

}

• Here array is already given. We can use same program to allow the user to input array elements as per wish by “while loop” and after getting array elements follow the similar steps as above.

☺ Pointers And Strings We know that, string is nothing but array of characters. Thus all the utilities of pointers & arrays are applicable to pointers and strings.

(1) char str1[] = “Dr. Vijay D. Gokhale”; char* str; str = str1; assigning base address of str1[] to pointer variable str. [ “&” not necessary] cout << str1 << “\n”; both will give cout << str << ”\n”; same output.

Note that in “C” & “C++”, to print all characters of a string [character array] loop is not necessary. Just mention the base address (either as array name – Eg. str1 OR as pointer variable name – Eg. str) of the string and “printf()” or “cout” will print all the string upto null character (“\0”).

(2) Similarly, by above example… str1++; illegal. Because “str1” is array name means it is base address,

and as address is constant it can’t be incremented or decremented str++; legal. Because “str” is pointer variable which

holds base address of string str1. (str = str1;) • Means Address itself can not be incremented or decremented, but pointer

variable which contains address, can be incremented or decremented. (3) As like array is passed to any function, a string also can be passed to any

function. # include <iosrtream.h> void main() { void display(char*); prototype char str1[] = “Dr. Vijay D. Gokhale”; display(str1); call to function with base address as parameter }

Page 109: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 109 By V. D. Gokhale

ASTROMEDICOMP

void display(char* str) function declarator with pointer { while(*str != ‘\o’) pointer value is printed

{ upto null character. cout << *str << ”\n”; str++; address is incremented using pointer variable. }

} (4) Copying A String

# include <iostream.h> void main() { void copy(char*, char*); string copy function char s[25] = “Dr. Vijay D. Gokhale”; s for “source” char t[25]; t for target copy(t, s); Base addresses (array names) of target & source strings

are passed cout << s << “\n”; print the source string cout << t << “\n”; print the copied (target) string.

} void copy(char* ptr2, char* ptr1) { while(*ptr1 != ‘\0’) loop until the source string reaches the null char. {

*ptr2 = *ptr1; copy each element of source into target ptr1++; after copying each element increment source ptr2++; string and target string pointer further }

*ptr2 = ‘\0’; after completing loop, means after every character of source string is copied to target string, give target

} string a null charaeter (5) Library string functions like strcpy, strlen, strcmp, strcat, strupr, strlwr are

based on above program. (6) Arrays of pointers to string

# include <iostream.h> void main() { const int DAYS = 7; char* week[DAYS] = {“SUNDAY”, “MONDAY”, “TUESDAY”,

“WEDNESDAY”, THURSDAY”, “FRIDAY”, “SATURDAY”};

Page 110: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 110 By V. D. Gokhale

ASTROMEDICOMP

for(int i=0; i<DAYS; ++i) { cout << week[i] << “\n”; }

} Here char* week[DAYS] is a Array of pointers, which can hold many

strings (equal to number of array size, here of “DAYS” size), each enclosed in pair of “ ” and separated by commas. All these strings together are enclosed in pair of { } and the declaration is terminated by semicolon. Array of Pointers to strings is nothing but an array of pointers to char, in 2 dimension.

* The “New & Delete” operators Arrays are a useful approach for data storage. When we declare int arr[100]; then compiler reserves memory for 100 integers. But these arrays have a serious drawback, that…..

1) We must know in advance, how big the array will be. 2) Once declared, array size can neither be increased nor be decreased, during the

runtime. 3) Thus we cannot get memory, if we need at run time. 4) Suppose we specify memory an array of 50 elements, then…

a) If we need less space at runtime, means less than 50, say 40, then 10 memory blocks are wastage of memory.

b) If we need more than 50 at runtime, then as we already said the size as 50, the system will hang or crash.

To overcome above problems, means to obtain extra memory blocks at runtime C++ provides a “new” named operator.

Similarly the obtained block of memory, after completion of program execution can be made free by “delete” named operator.

THE new OPERATOR This operator obtains memory from the operating system in the form of memory block (as per our requirement size) and returns a pointer to the storing address of that newly obtained memory block. Eg.

# include <iostream.h> # include <string.h> for string library functions like strlen, strcpy etc. void main()

{ char* str=”Dr. Vijay D. Gokhale”; char* ptr; int len;

Page 111: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 111 By V. D. Gokhale

ASTROMEDICOMP

len = strlen(str); getting length of given string. ptr = new char[len + 1]; getting memory (to hold above string) of specific

type & of specific size.”1” is for last ‘\0’ character in new string.

strcpy(ptr,str); copies “str” string in newly obtained memory block, which starts at address “ptr”.

cout << str << “ln”; prints original given string. cout << ptr << “ln”; prints copied string in new memory block.

delete ptr; frees the obtained memory and make it available to other programs.

} In this program ptr=new char[len+1]; statement returns a pointer (hold address of starting point of that memory block) which is assigned to another pointer “ptr”. Obviously “ptr” will contain the starting address of newly obtained memory block. By “new” word, we use “new” operator. By “char” word, we indicate that we want new memory block to hold some characters. Then square bracket pair is used. And in the square brackets the required size is mentioned. [size should be in bytes]. Here “len” gives the size of source string (str) but without a byte for a “\0” character. To give this null character to our target string (means to “ptr”) we add 1 in the original length of string. By strcpy() library function source string (str) is copied into the memory block whose storing address in “ptr”.

By two “cout” statements we print both strings, and prove that same sized memory block can be obtained by using “new” operator.

THE delete OPERATOR The last statement in previous program delete ptr; frees the newly obtained memory and make it again available to other programs. NOTE > The new operator should be used along with delete operator. Because if only new operator is used, then the obtained memory block will be permanently reserved for this program and it will waste the memory. As we want this block only at runtime, after execution, we don’t need this memory block and hence must be freed. ( In “C” the work of new operator was done by malloc(), calloc() like functions. But new is superior than them. Because it doesn’t need to declare “alloc.h” file inclusion and the pointer returned by malloc or calloc must be casted to appropriate data type, but new can itself identify to which data type the memory block is going to be assigned. The work of free() is done by delete.) * SYNTAX OF “new” OPERATOR

<pointer of proper data type> = new<data type [size in bytes]>;

Page 112: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 112 By V. D. Gokhale

ASTROMEDICOMP

OR

= new<user defined data type with/without size> * SYNTAX OF “delete” OPERATOR delete < the name of pointer of new memory block >;

* “Class String” using “new” and “delete” operator

# include < iostream.h > # include < string.h >

class string { private : char* str; public : string (char* s) constructor with one argument. with new operator.

{ int len;

len = strlen(s); str = new char[len + 1];

strcpy (str,s); }

~string() Destructor. with delete operator. {

delete str; } void display()

{ cout << str << “\n”;

} };

Page 113: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 113 By V. D. Gokhale

ASTROMEDICOMP

void main() { string s1=”Dr. Vijay D. Gokhale”; s1.display; }

As we know that Constructor function gets automatically executed when an

object is created, while Destructor function gets automatically executed when an object gets destroyed.

If we create such a constructor which receives a string [means starting address of string], then obviously constructor will have one argument of “pointer to char” type as char* s in this example.

The string class has only one private data item “pointer to char” type, which can hold the string (* str). Now we want to copy the user given string “s” in “str”.

“str” is not declared as array. Hence we don’t know the string size in advance. To overcome this problem, we get the length of given string and use “new” operator to get new memory block. As this operator is used in constructor, it will get created as soon as we declare object of class “string”. After copying a string, the job of constructor ends. Then s1.display() gets executed, displaying the copied string. Afetr execution of display() there is no other statement in main() hence the s1 object gets destroyed, causing destructor, which frees the obtained memory block.

This program gives 2 basic general rules 1) Generally “new” operator should be used in constructor functions, while, 2) “delete” operator should be used in destructor functions.

Pointers To Objects As we can assign a pointer variable to any data type, we also can assign pointer

variable to object too. When we declare a structure, then after declaring a structure variable, we can

refer to structure elements by “.” operator. And similarly when we declare a structure pointer, we can refer structure elements by “ “ operator.

Same above rules are applicable to objects too. • When we declare an object at a class, we can refer to class data members and

function members by “.” operator, as we had seen it many times in previous topics.

• When we declare a pointer to an object of a class, we can refer to class data members & function members by “ “ operator.

* SYNTAX OF ”Structure Pointer” DECLARATION

Page 114: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 114 By V. D. Gokhale

ASTROMEDICOMP

struct <user defined structure name> {

structure elements; } struct <structure name> * <user defined pointer variable name>;

* SYNTAX OF ”Object Pointer” DECLARATION

class <user defined class name> {

class booly; } <class name> * <user defined object pointer name>;

Eg # include < iostream.h > class vijay { private : int num; public : void getdata() {

cout << “ENTER AN INTEGER NUMBER :” << “\n”; cin >> num;

} void showdata() {

cout << “YOU ENTERED “ << NUM << “\n”; }

}; void main() {

vijay vobj; vijay* vptr; vobj.getdata(); object of a class, in which class member of the object vobj.showdata(); are accessed by “.” operator vptr->getdata(); pointer to object of a class, in which class members

Page 115: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 115 By V. D. Gokhale

ASTROMEDICOMP

vptr->showdata(); are accessed by “ “ operator. } Both above approaches will give same output on screen. * We can get an object pointer of pointing to starting of a memory block, which can have adequate amount of memory to hold class members by “new” operator. After using to pointer object properly we can free the assigned memory by “delete” operator. Eg vijay* vptr; vptr = new vijay; vptr->getdata(); vptr->showdata(); delete vptr; * Array Of Pointer To Objects

Suppose we want to print Name & Address of 100 persons, then we can do it by 2 ways [using object & class]. Similar work can be done by structure too.

# include < iostream.h> class vijay { private : char name[50], address[100]; public : void getdata()

{ cout << “ENTER NAME OF A PERSOON : “ << “\n”; cin.get(name,50); cout << “ENTER ADDRESS OF THE SAME PERSON :” << “\n”; cin.get(address,100); }

void showdata() { cout << “NAME : “ << name << “\n”; cout << “ADDRESS : “ << “\n”; } };

Approach I void main() { vijay v[100]; Array of 100 objects.

Page 116: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 116 By V. D. Gokhale

ASTROMEDICOMP

int i; for(i=0;i<100;++i)

{ v[i].getdata(); }

for(i=0;i<100;++i) { v[i].showdata(); }

}

Approach II void main() {

vijay* ptr[100] Array of 100 object pointer. int i; for(i=0;i<100;++i)

{ ptr[i] = new vijay; get memory by “new” ptr[i]->getdata(); }

for(i=0;i<100;++i) {

ptr[i]->showdata(); delete ptr[i]; free allocated memory by “delete”

} }

In both above approaches we have to enter all 100 records. Suppose, though space for 100 records are reserved and user wants to enter only few records, then following changes can be made…

void main() { vijay* ptr[100]; int I=0,j; char choice; do

Page 117: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 117 By V. D. Gokhale

ASTROMEDICOMP

{ ptr[i]=new vijay; get memory equal to object size. ptr[i]->getdata(); cout << “Do You Want To Enter More? [Y/N] “ << “\n”; cin >> choice; i++; }

while(choice==’Y’); after inputting ‘N’ loop will terminate and “i” will have value equal to entered record number.

for(j=0;j<i;++j) { cout << ptr[j]->showdata(); delete ptr[i]; free the obtained memory. } }

PONITERS TO POINTERS Suppose names of persons are entered, and we want them in sorted order

alphabetically. We can do this by using pointers. Initially we will create array of pointers to object. And then we will pass

address of two pointers (means address of addresses) to “sort” function to sort them alphabetically.

# include <iostream.h> # include <string.h> for strcmp function.

class person { private : char name[25]; public : void getname() { cout << “ENTER NAME “ << “\n”; cin >> name; } void showname() { cout << name << “\n”; }

char* retname() This is a function returning pointer to

Page 118: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 118 By V. D. Gokhale

ASTROMEDICOMP

{ return name; } char. Means storing address of name array. }; void main() { person* persptr[100]; array of object pointers of class person void sort(person**,int); pointer to array which is array of pointer

int i=0 , j; to objects (hence **) char choice; do { persptr[i] = new person; proper amount memory is obtained by persptr[i]->getname(); “new operator. i++; cout << “Do You Want To Enter Another? [Y/N]” << “\n”; cin >> choice; } while (choice == ‘Y’); cout << “Unsorted List : “ << “\n”; for(j=0; j<i; ++j) { persptr[j]->showname(); } It will print unsorted list of names. sort(persptr,i); function which takes array

name[address base] & size as its arguments. cout << “Sorted List : “ << “\n”; for(j=0;j<i;++j) { persptr[j]->showname(); It will print sorted list of names. }

}

void sort(person** pp , int n) similar to “sort” eg. in previous notebook { void order(person **,person **); prototype int k,l; for(k=0; k<n-l; ++k) { for(l=k;l<n;++l) { order( pp + k, pp + l); } }

Page 119: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 119 By V. D. Gokhale

ASTROMEDICOMP

} void order(person ** p1, person ** p2) { person * temp; if(strcmp((*p1)->retname(),(*p2)->retname() > 0) { *temp = *p1; *p1 = *p2; swapping *p2 = *temp; } } * Explanation When program gets executed, user starts entering names and when data finishes, user will enter ‘n’ and further program execution begins. At every time array of pointers of objects persptr[] will get filled by different names, and every time “memory” to hold that object will be set aside by “new” operator. After entering all desired records, the first loop of “persptr[j]->showdata();” will give “unsorted” list of names as per the sequence of user’s entry of data. For sorted list, function “sort” is written which takes two parameters, one is of “pointer to pointer to object” type and another is an integer means this function receives a> Address of the array “persptr” and address of the each elements in that array. Means Address of array is “person *” but the array is itself of pointers, hence “person **” which will now refer to each element of that array. In the function body of “sort” is created to refer to every elements of this array. “Sorting of anything is done by comparing first with the next”. Hence in the function “sort” another function is prototyped named “order”, which receives 2 prototypes of “pointer to pointer to object” type for the sake of comparison. Obviously first parameter will be compared with the next parameter, and by this way every name will be compared with all other names. For comparison of the names, we need “string compare function”, which is strcmp()

strcmp will return <0 if first string comes before second string. strcmp will return 0 if first string and second string are exactly same. strcmp will return >0 if first string comes after second string.

In function “order” two strings are compared by “>0” option, so that if it becomes true, then second string will get position of the first string and first string will get position of second string by swapping.

Now to refer each string… p1 is itself a pointer to object. Hence if we say p1->retname(), it will give

reference to object, not to content of that object, hence (*p1)-> retname() form is use, now “*” mark will enter in that object, to which p1 is pointing.

Page 120: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 120 By V. D. Gokhale

ASTROMEDICOMP

*p1 is the value of content of p1, which is itself a pointer. * Debugging Pointer Pointer can be the source of serious program bugs. The most common problem occurs when programmer fails to place a valid address in a pointer variable. When such thing occurs, then pointer can point any address in the memory, which may crash the system. Particularly when we declare a pointer variable globally, we know that all global variables are initialized to 0. Hence if we declare int *ptr; globally and in the program if we write *ptr=30; then compiler will shoot error of “Null Pointer assignment”. Because due to global declaration *ptr has value 0, and statement *ptr=30; is failed to put value 30 in place of address 0. When such problem occurs…

a) usually keep pointer variables local to functions, b) by “watch window” facility to check the contents at address 0, for this type the

expression *(char *) 0, 4m in the watch window. Here 0 is casted to “pointer to char” and 4m denotes compiler to show 4 bytes of

memory. These 4 bytes are usually “0”, when they are something else, then there is

problem.

VIRTUAL FUNCTIONS AND OTHER SUBTLETIES Virtual Function >> Virtual means existing in effect but not in reality. Then virtual functions become those functions which do not really exist (means their bodies) in base classes but they appear with their bodies in derived classes of that base class. Suppose we have a base class “shape” and there are 3 derived classes from “shape” are “triangle”, “circle” and “square”. All these derived classes have a function called draw() and by polymorphism, all can have different parameters (both in type and number) and different codes to draw respective shapes. As we put common things of derived classes in base class, we also put draw() function in base class “shape”, with either no code or with a default shape rectangle’s code. If we want to draw a picture with shapes, in main() if we declare array of pointers to base like shape * ptrpicture[100]; In the future code if assign address of derived classes to above pointers correctly, then we can draw the picture by using just a simple loop like… for(int i=0; i<100; i++) ptrpicture->draw(); This very simple 2 line code can draw a whole picture because when ptrpicture pointer points to draw() of triangle, it will draw triangle, when it points to draw()

Page 121: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 121 By V. D. Gokhale

ASTROMEDICOMP

of circle, it will draw circle and when it points to draw() of square, it will draw square. But to get above work done, we must make draw() of base class “shape” as virtual with no code. Why? We can clear the question by taking one example.

# include <iostream.h> //namespace class Base { public : Base class void show() with show()

{ as public. cout << Base \n”;

} }; class Derived1 : public Base { public : first derived class from base void show() class with public access, having

{ show() of its own, public. cout << “Derived1 \n”; }

}; class Derived2 : public Base { public : 2nd derived class from base class void show() with public access, having

{ show() of its own, public. cout << “Derived2 \n”; }

}; void main() { Derived1 dv1; Derived2 dv2; Base * ptr;

ptr = &dv1; ptr->show(); ptr = &dv2; ptr->show(); }

Page 122: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 122 By V. D. Gokhale

ASTROMEDICOMP

The Output is… Base not at all Base expected In above example, there is a base class “Base” and 2 derived classes of “Base” are “Derived1” & “Derived2”. As both derived classes are derived “public” access specifier, public items of base class become public to derived class. Thus show() function of class “Base” is public to both derived classes and derived classes themselves have draw() function too. In main() we declare 2 objects of derived classes as “dv1” & “dv2”. Also we declare a pointer to “Base” class as “ptr”. Next we assign address of dv1 to ptr, as ptr = &dv1; Here one question arise, how object of different type gets assigned to pointer of some other different type? Because if we have float * ptr and int num, then we can not do ptr = &num; Hence ptr points to float type and we are assigning address of integer to it. Hence compiler will flag error in this situation. But surprisingly for ptr = &dv1 compiler doesn’t give error, why? Because pointer to object of derived class are type compatible with the pointer to object of the base class. Thus ptr = &dv1; is perfectly legal. Now using “ptr” we call show() as

ptr->show(). Same above 2 line code is also repeated for “dv2” object too as… ptr = &dv2; ptr->show(); Now as “ptr” is pointing (in both above situations) to derived classes we expect output as… Derived1 Derived2 But the actual output is… Base Base This shows that the show() of Base class is executed for both above classes. Means when derived classes have “same named function” as that of base class, then base class function dominates an derived class function if they are called by using pointer to base class and putting address of object of derived class in that pointer. Thus here compiler ignores the content in ptr (here &dv1 or &dv2) and chooses the member function of the same name of base class (obviously if present). Means it prefers type of the pointer (base *) and not content of pointer(&dv1 etc). Sometimes this may be the actual requirement. But our problem is to access object of different classes using

Page 123: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 123 By V. D. Gokhale

ASTROMEDICOMP

one same statement only and getting different outputs (as explained for drawing different shapes with one single same statement ptrpicture->draw() ) and this problem still remains unresolved. This problem can be solved by using a single keyword virtual. Just go to base class and put the keyword virtual in the declaration of the function (with same name as in derived class function). That is… class Base { public : virtual void show() { cout << “Base \n”; } }; By making only this change, we get the output… Derived1 Derived2 …which is our actual goal.

What the magic done by the keyword “virtual”? When compiler sees the keyword virtual and when a pointer to base class is

created, which is then assigned to the address of the object of derived class, it gives more importance to the content in the pointer instead of type of the pointer. (Note > This is exactly opposite to the situation when there was no “virtual” keyword) And this is what we want.

When there was no “virtual” keyword, compiler just ignored all the derived classes and executed the function at base class. But when it looks “virtual” it gets puzzled, which version of show() is to be executed? So it keeps this decision aside for runtime. During runtime compiler becomes aware that the pointer of base class is pointing to the object of derived class. Thus compiler executes the function in derived class.

As this decision is made during runtime, this is called as Dynamic Binding or late binding. Otherwise for non-virtual functions, compiler chooses functions during compilation time and doesn’t wait for runtime. This is called as Static Binding or early binding. Though Dynamic or late binding requires some additional code (like mentioning virtual), it is more flexible and powerful. * Pure Virtual Function In above situation when we don’t want the function of base class to execute, instead we want the same named function in derived class to execute, then why to write code (body) for the function in base class? Yes, we can do it. When we are sure that, we are not going to use a function in the base class, but we want to execute the same function in derived class and,

Page 124: C++ PROGRAMMING BASICS · Bur in C++, for input and output inclusion of standard library file iostream.h is must. (This is done by typing #include  on the top of

C++ Notes 124 By V. D. Gokhale

ASTROMEDICOMP

obviously derived classes have different codes for that function respectively (i.e. polymorphism), then… 1) Don’t write body for such function in base class. 2) Just write its decelerator with “virtual” keyword. 3) Obviously, we are not going to use this function from base class, it may or may not have any parameters, but the return value must be common (means if you declare a pure virtual function with “void” as return value in base class, then derived 2 classes must have “void” return value for this function. Parameters may be different in number or type(polymorphism).) 4) After writing decelerator just add “=0” at the end of decelerator. 5) semicolon. Eg. class Base { public : virtual void show()=0; }; Such a function which does not have function body and which is virtual, is now called as Pure Virtual Function (“=0” is just a syntax not an assignment). Then a question arises… if we are not going to use the base class function and it it does not have any code, then why to write it? Can’t we omit it? No, we can’t omit its declaration in the base class. Because as we want to use base class pointer (Base * ptr), the thing to which it points to, must be a member of the base class. Thus its mentioning is must, though actual execution of the member function of derived class is to be done. Note that, pure virtual function body is omitted in the base class on assumption that, programmer will write different bodies of this function in different derived classes of this base class. Thus though function body of pure virtual function is absent in base, it is going to be present in one of its derived class. * Abstraction Class Some times it may happen that, we need a base class just to derive other classes from it. But we do not need object of base class to be created anywhere in the program. Then such a class is called as Abstract Class. Thus abstract class remains just as a platform to derive classes from it by inheritance. It must follow these thumb rules… 1) No objects can be created of such base classes. 2) But pointer pointing to base class can be declared. 3) It must have at least one pure virtual function. All other classes which are not abstract are called as Instance Classes as we create at least one instance (i.e. object) from them.