Unix, C & C++ UNIT - IV Snapshot
Introduction to Object Oriented Programming Features of OOPs Basic Concepts of OOPs Principles of OOPs Applications of OOPs Introduction to C++ Problems in software Development Variables, Constants and data types Keywords Introduction to input and output Simple C++ Program Compiling and Executing a program Operators Introduction to Control Structures Loops The break and continue Statements The goto statement Defining Classes and Objects Function & its Types Function Overloading Constructors Destructors Friend Function Operator Overloading
4.0
Introduction
A conventional programming language such as C is known as procedureoriented programming. In the procedure-oriented approach, the problem is viewed as a sequence of things to be done, such as reading, calculating and printing. A number of functions are written to accomplish these tasks. The primary focus is on functions. In a multi-function program, many important data items are placed as global so that they may be accessed by all the functions. Each function may have its own local data. Global data are more vulnerable to an inadvertent change by a function. In a large program it is very difficult to identify what data is used by which function. Another serious drawback with the procedural approach is that it does not model real world problems very well.
Page 51
Unix, C & C++
The major motivating factor in the invention of Object-Oriented Programming (OOP) approach is to salvage some of the flaws encountered in the procedural approach. OOP treats data as a critical element in the program development and does not allow it to flow freely around the system. It ties data more closely to the functions that operate on it and protects it from accidental modification from outside functions. OOP is used to decompose a problem into a number of entities called objects and then builds data and functions around these entities used to decompose a problem into a number of entities called objects and then builds data and functions around these entities. Until recently, programs were thought of as a series of procedures that acted upon a set of data. A procedure or function is a set of specific instructions executed one after the other. The data was quite separate from the procedures and the trick in programming was to keep track of which functions calling other functions and what was the data that was changed. To make sense of this potentially confusing situation, structured programming was created. The principle idea behind structured programming is simple: divide and conquer. A computer program can be thought of as consisting of a set of tasks. Any task that is too complex would be broken down into a set of smaller component tasks, until the tasks were sufficiently small and self-contained enough that they were easily understood. For example, consider a complex task of computing the average salary of every employee of a company. It can be broken down into subtasks such as, finding out what each person earns, counting the number of people, summing up all the salaries and dividing the total by the number of people. The total of all the salaries can also be broken down into subtasks such as, getting each employees record, accessing the salary, adding the salary to the running total and getting the next employees record. Obtaining each employees record can in turn be broken down as opening the file of employees, going to the correct record and reading the data from disk. Structured programming remains an enormously successful approach for dealing with complex problems. But, by the late 1980s, some of the deficiencies of structured programming had become too clear. There was a difficulty in separating the data structures from functions that manipulated the data. The other disadvantage was that the programmers found themselves constantly reinventing new solutions to old problems. The idea behind reusability is to build components that have known properties and then to be able to plug them into the program as and when it is needed. This is modeled after the hardware world. For instance, when engineers need a new transistor, they do not invent one, they go to a big bin of transistors and finds one that works the way they need or perhaps modify it. No similar option existed for a software engineer. Object-oriented programming attempts to respond to these needs, providing techniques for managing enormous complexity, achieving reuse of software components and coupling data with the tasks that manipulate the data. The essence of object-oriented programming is to treat data and the procedures that act upon the data as a single object, a self-contained entity with an identity and certain characteristics of its own.
Page 52
Unix, C & C++ 4.1 Objective
The objective of this lesson is to understand the fundamentals of Object Oriented Programming, which include a wide range of topics from fundamentals of Object Oriented Programming and Features of OOPs to type conversion. The fundamental concepts include defining classes and objects, Array of objects, function and its types, function overloading and operator overloading. At the end of the lesson you learn about constructors, destructors, copy constructor and friend function.
4.2
4.2.1 [Link]
Content
Object Oriented Programming Features of OOPs
Object-oriented programming is an approach that provides a way of modularizing programs by creating partitioned memory area for both data and functions that can be used as templates for creating copies of such modules on demand. That is, an object is considered to be a partitioned area of computer memory that stores data and set of operations that can access that data. Since the memory partitions are independent, the objects can be used in a variety of different programs without modifications. The features of OOPs are as follows: Emphasis is on data rather than procedure. Follows bottom-up approach in program design. Programs are divided into objects. New data and functions can be easily added. Data structures are designed such that they characterize the objects. Functions that operate on the data of an object are tied together in the data structure. Data is hidden and cannot be accessed by external functions. Objects may communicate with each other through functions. [Link] Basic Concepts of OOPs
Object-Oriented programming concepts are as follows: Objects When one approaches a programming problem in an object-oriented language, one no longer ask how the problem will be divided into functions, but how it will be divided into objects. Thinking in terms of objects, rather than functions, has a surprisingly helpful effect on how easily programs can be designed. This results from the close match between objects in programming sense and objects in the real world.
Page 53
Unix, C & C++
Object may represent a person, a place, a bank account, a table of data or any item that the program must handle. When a program is executed, the objects interact by sending messages to one another. Classes In OOP, objects are members of classes. A Class serves as a plan or template. It specifies what data and what functions will be included in objects of that class. Defining the class does not create any objects. A class is a collection of similar objects. Data Abstraction and Encapsulation The winding up of data and function into a single unit (called class) is known as encapsulation. Data encapsulation is the most striking feature of class. The data is not accessible to the outside world and only those functions, which are wrapped in the class, can access it. These functions provide the interface between the objects data and the program. This insulation of the data from direct access by the program is called data hiding. Classes use the concept of abstraction and are defined as a list of abstract attributes such as size, weight, cost and functions to operate on these attributes. They encapsulate all the essential properties of the objects that are to be created. Since the classes use the concept of data abstractions, they are known as Abstract Data Types (ADT). Inheritance Inheritance is the process by which objects of one class acquire the properties of another class. The principle behind this sort of division is that each subclass shares common characteristics with the class from which it was derived. In a similar way an OOP class can be divided into subclasses. In C++ the original class is called the base class. Other classes can be derived that has the characteristics of the base class along with additional features. These are called derived classes. Polymorphism Polymorphism means the ability to take more than one form. For example, an operation may exhibit different behavior in different instances. The behavior depends upon the types of data used in the operation. Polymorphism plays an important role in allowing objects having different internal structures to share the same external interface. This means that a general class of operations may be accessed in the same manner even though a specific action associated with each operation may differ. Polymorphism is extensively used in implementing inheritance. Dynamic Binding Dynamic binding means that the code associated with a given procedure call is not known until run-time. It is associated with polymorphism and inheritance.
Page 54
Unix, C & C++
Message Communication An object-oriented program consists of a set of objects that communicate with each other. The process of programming in an object-oriented language involves the following basic steps: Creating classes that define objects and their behavior. Creating objects from class definitions. Establishing communication among objects. Objects communicate with one another by sending and receiving information in the same way as people pass message to one another. The concept of message passing makes it easier to talk about building systems that directly model or simulate their realworld counterparts. A message for an object is a request for execution of a procedure and therefore will invoke a function (procedure) in the receiving object that generates the desired result. Message passing involves specifying the name of the object, name of the function (message) and the information to be sent. [Link] Principles of OOP
OOP offers several benefits to both the program designer and the user. It solves many problems associated with the development and quality of software products. The new technology promises greater productivity, better quality of software and lesser maintenance cost. The principle advantages are: Inheritance is used to eliminate redundant code and extend the use of existing classes. The user can build programs from the standard working modules that communicate with one another, rather than having to start writing the code from first. The Principle of data hiding helps the programmer to build secure programs that cannot be invaded by code in other part of the program. It is possible to have multiple instances of an object to co-exist without any interface. It is possible to map objects in the problem domain to these objects in the program. Based on the objects, it is easy to partition the work. The data-centered design approach enables the user to capture more details of a model in implementable form. Object-oriented systems can be easily upgraded from small to large systems. Software complexity can be easily managed. [Link] Problems in Software development
Page 55
Unix, C & C++
Development in software technology continues to be dynamic. New tools and techniques are announced in quick succession. This has forced the software industry and software engineers to continuously look for new approaches to software design and development, which is becoming more and more critical in view of the increasing complexity of software systems as well as the highly competitive nature of the industry. These things have created a serious crisis within the industry. The following issues need to be resolved to overcome this crises: [Link] How to represent real-life entities of problem in system design? How to design systems with open interface? How to ensure reusability and extensibility of modules? How to develop modules that are tolerant to any changes in future? How to manage time schedules? How to improve the quality of software? Applications of OOP
OOP has become one of the programming buzzwords today. It appears to be a great deal of excitement and interest among software engineers in using OOP. The most popular application of object-oriented programming has been in the area of user interface design such as Windows. There are hundreds of windowing systems developed using OOP techniques. Real-business systems are often much more complex and contain many more objects with complicated attributes and methods. OOP is useful in this type of applications because it can simplify a complex problem. The object-oriented paradigm sprang from the language, has matured into design and has enabled software industry to improve not only the quality of software systems but also its productivity. 4.2.2 Introduction to C++
C++ is an object-oriented programming language. Initial name was C with classes. C++ was developed by Bjarne Stroustrup at AT & T Bell Laboratories in Murray Hill, New Jersey, USA, in the early eighties. The idea of C++ comes from the C increment operator ++, thereby suggesting that C++ is augmented (incremented) version of C++. The three most important facilities that C++ adds on to C are Classes, Function Overloading and Operator Overloading. These features enable to create abstract data types, inherit properties from existing data types and support polymorphism, thus making C++ a truly object-oriented language. The object-oriented features in C++ allow programmers to build large programs with clarity, extensibility and ease of maintenance, incorporating the spirit and efficiency of C. The addition of new features has transformed C from a language that currently
Page 56
Unix, C & C++
facilitated top-down, structured design, to one that provides bottom-up, object-oriented design. Variables Variables are storage units for values. They refer to a memory location where the value will be stored. There are different types of variables. Depending on the type of variable, the value stored in it will vary. This means that if a numeric value is to be stored, only a numeric variable is to be used. In other words, a numeric variable can hold only a number. Naming a variable Whenever a value stored in a variable is to be used, the name of the variable should be mentioned. A variable name should confirm to certain rules. The name of the variable should always start with an alphabet. The characters other than the first character can be either number or alphabet. Punctuation characters and spaces are not permitted. A keyword (explained later) cannot be used as a name of the variable. The name is case sensitive. This means that the upper case and lower case of the same alphabet are different. Thus two variables can be defined having names as a and A respectively.
Constants A constant unlike variable cannot be assigned a new value once assigned. A constant is assigned a value during declaration. The keyword const is used to create a constant. Example const int a =5; In this case a is a constant. Notice the use of the keyword const. Also note that a value 5 is assigned to the variable a. So a will retain this value through out the program and it can never be changed. If an attempt is made to change the value it will result in error. Data types Every variable has a data type which decides the type of value, a variable can hold. The data type of a variable is to be specified when the variable is first created. The data type decides the type of the content a variable (and hence a memory location) can hold and lays down certain rules about what kind of operation a variable can do . C++ supports seven basic data types as listed below. Type Name char short int long Used to Store Characters Small whole numbers Normal sized whole numbers Large whole numbers Page 57
Unix, C & C++
float double long double Variable Declaration Small real numbers Large real numbers Extra-large real numbers
Applying a name and a type to a variable is called variable declaration. A declaration has the following form: type list of variables where, type refers to the data type of a variable. list of variables refer to the variable names of that particular data type. The variables in a list are separated by a comma. Each variable in a list is declared to be of same type. Different types of variables are declared in different statements. A variable should be declared at start of a program or atleast before it is used. Example int a; In this case a variable called a is declared to be of type int. This means that this variable a can hold only whole numbers. int a,b; In this case two variables called a and b are declared to be of type int. Note that the two variables are separated by a ,. Both the variables in this case can hold only whole numbers Suppose the variable b has to hold a real number then the above variable declaration statement can be modified as int a; float b; Assigning a value to a variable A newly declared variable is not set to any value. Unless a value is explicitly assigned to it, it takes a random value. A variable is assigned a value by using an = symbol. The value assigned to a variable is retained until the variable is assigned a new value or the program terminates. Example a=5; b=6.5; In the above example, the variable a is assigned a value of 5 while the value 6.5 is assigned to b. Note that the variable should come on the left hand side of the = sign Page 58
Unix, C & C++
while the value to be assigned should come on the right hand side of the = sign. A variable can also be assigned to another variable provided the variable that comes on the right hand side has a value. This is illustrated in the example given below. Example int a,b; a=3; b=a; Keywords Keywords are special words that have a specific meaning in a computer language. They are reserved words that inform the compiler about the important constructs in a program. The keywords cannot be used as names for program variables. The table below lists the keywords used in C++. Keywords in C++ asm class else goto operator short template unsigned auto const enum if private signed this virtual break continue extern inline protected sizeof throw void case default float int public static try volatile Catch Do For Long Register Struct Typedef While char double friend new return switch union
4.2.3
Introduction to I/O
Any program requires certain data to process and finally gives a result based on the data fed to it. The data given to the program is called input and the final result from the program is called output. cout statement In C++, cout is used for output. Here is a statement that displays a line of text on the screen. cout<< This text will appear on the screen.; In a cout statement, anything given within double quotes ( symbol), will be displayed as it is on the standard output device, the monitor. The operator << used with cout is called the insertion operator. When a value of a variable is to be displayed, then that variable name has to be specified next to the insertion operator as shown in the example below: Example Page 59
Unix, C & C++
int a=5; cout<<a; The above example will display an output of 5, which is the value of the variable a, on the screen. endl It is a keyword used along with cout statement to mark the end of a line. Once an endl keyword is encountered, the contents that follow it will be displayed in the next line. Example cout<< Hello<<endl; cout<< World; The above statements will display Hello in the first line and World in the next line as shown below: Hello World Had endl not been used in the cout statement, both Hello and World would appear in the same line. cin statement cin statement is used for input. A variable can be assigned a value directly using an = sign as discussed earlier. If a variable has to be assigned a value when the program is executed, cin statement is used. The general syntax of cin statement is: cin>>list of variables The symbol >> is called an extraction operator. Example int a,b; cin>>a>>b; In this example, a and b are not assigned any initial value. When the program is executed, the values for a and b are to be supplied by the user. Simple C++ program
Page 60
Unix, C & C++
Any program will start its execution from the main() function. A function refers to a set of statements grouped logically to perform certain task. The main() function consists of a set of statements, which will be executed one after another. The statements that constitute the main function are enclosed within curly braces ( { } ). Consider a program for adding two numbers and displaying the result. In C++ program any number or character needs to be stored in a variable. From the algorithm it is clear that three variables are required to store the numbers (the 2 numbers that have to be summed up and the answer). Since all the variables are used for storing numbers, their data type can be int. Thus the first statement in C++ program should be int a, b, c; The above statement declares three variables a,b and c, all of type int. All statements in C++ should end with a semicolon and hence the above statement also ends with a semicolon. Now, the two numbers have to be accepted before proceeding on to anything else. These steps can be implemented using statements like: a=5; b=6; Both these statements assign a value to the variable a and b. These are the values whose sum has to be found out. Note in this case, the values are not accepted from the user but a known value is directly assigned to each of the two variables using an = symbol. According to steps 3 and 4 in algorithm, the two variables should be added up and the result has to be stored. Both these steps can be represented using a single statement as follows in C++. c=a+b; The statement above first adds the values of a and b and then assigns the value to c. The last and the most important step is to get the answer. This can be achieved using a cout<< as follows: cout<< The sum is : << c; The above statement first displays the string enclosed in double quotes and then prints the value stored in the variable c. With these steps the statements required for Page 61
Unix, C & C++
writing a C++ program is complete. One important thing to be noted while writing a C++ program is that all the statements have to be enclosed within the function main() between the two braces. Thus, a complete C++ program will look like the one shown below: #include<iostream.h> main() { int a,b,c; a=5; b=6; c=a+b; cout<< The sum is :<<c; } Output: The sum is : 11 The above program will always display the output as 11. If a different set of numbers are to be added, it will be a better option to supply the values during run time. The above program can be modified as follows: #include<iostream.h> main() { int a,b,c; cout<< Enter 2 numbers:<<endl; cin>>a>>b; c=a+b; cout<< The sum is:<<c; } Input: Enter 2 numbers: 2 3 Output: The sum is: 5 The second version of the program would be a better option if a sum of various sets of numbers is to be computed.
Page 62
Unix, C & C++
Preprocessor directive In both the programs above, note the use of #include<iostream.h>. This statement is called preprocessor directive. This causes the preprocessor to add the contents of the iostream.h file to the program. The file iostream.h is called header file. Depending on the type of function to be performed, an appropriate header file has to be included. There are different header files. If a mathematical function like sin() or cos() has to be used, the header file math.h has to be included. The header file iostream.h has to be included whenever cin and cout have to be used in the program. #include<iostream.h> #include<math.h> main() { int a,b,c; a=2; b=3; c=pow(a,b); cout<< Answer: <<c; } Output: Answer: 8 In the above program a new function pow() has been used. This is for finding the power of a number. This means that a statement pow(a,b) gives the value of ab . The program hence displays the result as 8 as 23 =8. The function pow() is actually defined in a header file called math.h. The program, therefore includes the header file <math.h>. If this statement is omitted, the program cannot recognize the function pow() and will display an error message. Compiling and executing a program Mere typing of a program will not produce any output. The typed program called source code has to be compiled. The compilation is the process by which the syntax of the program is checked and then converted to object file. The compilation process is followed by a linking process during which the library functions are linked automatically with the object file to produce an executable file. The executable file when executed produces the desired output. The entire process of compiling, linking and executing the program can be represented as follows:
C++ Source file
COMPILER
Object file
LINKER
Executable file
Page 63
Library functions
Unix, C & C++
Comments A comment is just some text enclosed in a pair of comment delimiters. The text between the comment delimiters can be anything; whatever falls between the delimiters is simply ignored by the compiler. The comments are used for conveying information about what the code does in plain English. There are two of comments- multi line comment and line end comment. Multi-line comments are used when the comment runs to more than 1 line. In such case the comment text is enclosed between /* and */. Line end comment is one that begins somewhere within a line of C++ code and then terminates at the end of the line. The line end comment delimiter is a double forward slash, //. Heres an example: a=5; // a takes the value of 5 There is only one line-end comment delimiter; it doesnot enclose the text. The following program uses comments in the program for the sake of clarity. #include<iostream.h> main() { int x,y,z; //Declaring 3 variables as integer cout<< Enter value for x and y numbers :<<endl; cin>>x>>y; //accepts value for x and y z=x*y; // computes the product of x and y and stores in z cout<< The product is:<<z; // this statement displays the output of z. } Output: Enter value for x and y numbers: 5 6 The product is: 30 The above program uses comments along with most of the statements in the program. This makes the program comprehensible for even people who do not know programming. 4.2.4 Operators & Manipulators Data is manipulated by symbols called operators in the C++ programming language. Much like the common math set of operators; C++ has its own operators for the manipulation of data. Operators are commonly used in mathematical calculations and in allocating or addressing a variable. They can also be used for logical comparison. Operators can be classified into a number of categories. They are: Arithmetic operators Relational operators Logical operators Assignment operators Page 64
Unix, C & C++
Conditional Operator (Ternary operator) Bitwise operators Increment and decrement operators.
Besides the above classification, operators can be classified into two groups: unary and binary. A unary operator works on one value also called an operand. An example of a unary operator is the negation operator. The negation operator is placed before a variable, and it returns the opposite sign of the variable. So if a variable 'x' containing a value of -5 is prefixed with the negation operator, the result would be 5. A binary operator requires two values to work with. There are more binary operators than unary operators. Examples of binary operators include + addition, - subtraction, * multiplication, / division and % modulus. Every operator has two important properties called precedence and associativity. Both the properties affect how operands are attached to operators. Operators of higher precedence will operate first on the operands regardless the way they appear in the expression. For example multiplication has higher precedence over addition, so the expression 2+3*4 will be evaluated as (2+(3* 4)) = (2+12)=14 and not as (2+3)*4 = 5*4 = 20. In cases where operators have same precedence the order is determined by associativity. The grouping occurs either from right to left or from left to right depending on the operator. The table shown below clearly states the precedence and associativity. Description Function expression Array expression Structure operator (indirection) Structure operator (dot) Unary minus Increment/decrement Ones complement Negation Address of Value at address Type cast Size in bytes Multiplication Division Modulo Addition Subtraction Left shift Operator () [] -> . ++, -~ ! & * (type) sizeof * / % + << Associativity Left to Right Left to Right Left to Right Left to Right Right to Left Right to Left Right to Left Right to Left Right to Left Right to Left Right to Left Right to Left Left to Right Left to Right Left to Right Left to Right Left to Right Left to Right
Page 65
Unix, C & C++
Right Shift Less than Less than or equal to Greater than Greater than or equal to Equal to Not equal to Bitwise AND Bitwise Exclusive OR (XOR) Bitwise inclusive OR Logical AND Logical OR Conditional Assignment >> < <= > >= == != & ^ | && || ?: = *=, /=, %= +=, -=, &= ^=, |= <<=,>>= , Left to Right Left to Right Left to Right Left to Right Left to Right Left to Right Left to Right Left to Right Left to Right Left to Right Left to Right Left to Right Right to Left Right to Left Right to Left Right to Left Right to Left Right to Left Right to Left
Comma Arithmetic operators
Operators like +, -, *, / are well known and they perform usual addition, subtraction, multiplication and division respectively. There are some operators that need more attention at this stage. The Unary minus (-) operator The subtraction operator can sometimes be used in the unary form on one operand and it performs the function of arithmetic negation. In effect it multiplies its single operand by -1. So, -a changes the sign of the number a. The Modulus (%) operator The modulo (%) operator is used to obtain the remainder when one integer is divided by another. So, a%b returns the remainder obtained when a is divided by b. a and b can be only of integer data type. For Example,
Page 66
Unix, C & C++
5%3 gives 2. Relational Operators Often it is required to compare two quantities and depending on their relation, take decisions. These comparisons can be done with the help of relational operators. The value of a relational expression is either one or zero implying, the relation is true or false respectively. For example, 30 < 40 is true (or one) and 40 < 30 is false (or zero) Logical Operators In addition to the relational operators, C contains two logical operators(also called Logical connectives). They are && - logical and operator || - logical or operator Logical operators act upon operands that are themselves logical expressions. The net effect is to combine the individual logical expressions into more complex conditions that are either true or false. The result of logical and operation will be true only if both the operands are true whereas, the result of logical or operation will be true if either one of the operand is true or both the operands are true. For example: Let the value of i be 2 and c be [Link] (i>0) && (c<2) will be false while (i>0) || (c<2) will be true. Assignment Operators Assignment operators are used to assign a value, result of an expression or the value of another variable to a variable. The general form is Variable = Value or Variable = Expression or Variable = Variable Assignment operators can also be combined with arithmetic operators. The shorthand form of this combination is as follows. Variable binaryoperator= expression This is equivalent to saying Variable = Variable binaryoperator expression Consider an example
Page 67
Unix, C & C++
X += 5; This is the same as X = X + 5; These shorthand assignment operators help to make the statement look more concise and easier to read, which is very desirable in programming. The following are the commonly used assignment combo operators: += Addition assignment -= subtraction assignment *= multiplication assignment /= division assignment %= modulus assignment (remainder from division)
Conditional Operators (Ternary operator) A ternary operator pair "?:" is available in C++ to construct conditional expression of the form exp1 ? exp2 : exp3; where exp1, exp2 and exp3 are expressions. This operator works as follows: exp1 is evaluated first. If it is nonzero (true), then the expression exp2 is evaluated and becomes the value of the expression. If exp1 is zero (false), exp3 is evaluated and becomes the value of the expression. Note that only one of the two expressions (either exp2 or exp3) is evaluated. Consider the example: x = (a>b) ? a*10 : b /5; This is the same as saying If (a>b) x = a*10; else x = b/5; Bitwise Operators C++ has a distinction of supporting special operators known as bitwise operators for manipulation of data at the bit level. These bits are used for testing the bits or shifting them from right to left Operator Use Page 68 Operation
Unix, C & C++
>> << & | ^ ~ op1 >> op2 op1 << op2 op1 & op2 op1 | op2 op1^op2 ~op2 shift bits of op1 right times shift bits of op1 left times bitwise and bitwise or bitwise xor bitwise complement
The shift operators simply shift the bits of the left-hand operand over by the number of positions indicated by the right-hand operand. The shift occurs in the direction indicated by the operator itself. For example, the following statement, shifts the bits of the integer 13 to the right by one position: 13 >> 1; The binary representation of the number 13 is 1101. The result of the shift operation is 1101 shifted to the right by one position--110 or 6 in decimal. Thus, the bit farthest to the right is lost. A right shift of 1 bit is equivalent to, but more efficient than, dividing the left-hand operand by 2. A left shift of 1 bit is equivalent to multiplying by 2. The bitwise and (&) operation performs the "and" function on each parallel pair of bits in each operand. The "and" function sets the resulting bit to 1 if both operands are 1. The following table shows the result of AND operation done on one bit. op1 0 0 1 1 op2 0 1 0 1 Result 0 0 0 1
Suppose the values 12 and 13 are to be anded: 12 & 13 The result of this operation is 12. This is because, the binary representation of 12 is 1100, and the binary representation of 13 is 1101. The "and" function sets the resulting bit to 1 if both operand bits are 1, otherwise, the resulting bit is 0. So, if the two operands are lined up the and function is performed the two high-order bits of each operand are 1. Thus the resulting bit in the result is also 1. The low-order bits evaluate to 0 because either one or both bits in the operands are 0. 1101 & 1100 -----1100
Page 69
Unix, C & C++
The | operator performs the inclusive or operation and ^ performs the exclusive or operation. Inclusive or means that if either of the two bits are 1 then the result is 1. The following table shows the results of inclusive or operations: op1 0 0 1 1 op2 0 1 0 1 Result 0 1 1 1
Exclusive or means that if the two operand bits are different the result is 1, otherwise the result is 0. The following table shows the results of exclusive or operation. op1 0 0 1 1 op2 0 1 0 1 Result 0 1 1 0
And finally, the complement operator inverts the value of each bit of the operand: if the operand bit is 1 the result is 0 and if the operand bit is 0 the result is 1. Increment and Decrement Operators The increment and decrement operators are very useful operators and are not commonly found in other languages. They are represented as ++ and -The operator ++ adds 1 to the operand while -- subtracts 1 from its operand. Both are unary operators and take the following form: ++m m++ --m m-- pre increment post increment pre decrement post decrement
These operators come in handy while writing the loop statements. Note: The evaluation order becomes increment/decrement operators. For example: int x=8,y=3,z; z = x++ * ++y; Page 70 important while handling these
Unix, C & C++
Here z will be evaluated as 32. This is because the variable x is post incremented. So operation is done after the expression is evaluated. So while evaluating the expression x is still 8. But y is pre-incremented, that is, the operation is done before evaluating. So y will be evaluated to 4. So the final expression is evaluated as 8 * 4 = 32. After evaluation is done x is operated by post-increment operator. So x will now become 9. 4.2.5 Basic Control Structures The flow of a program depends on the flexibility offered by the language, in terms of the functionality and programming control features. C++ offers a number of control structures for this purpose. Control structures help in changing the flow of execution of the program. There are several elegant and simple structures for looping and conditional branching. They are: The if Statement The if-else Statement The switch case Statement The if Statement The if statements allows branching (decision making) depending upon the value or state of variables or result of an expression. This allows statements to be executed or skipped, depending upon decisions. The basic format is, if( expression ) program statement; Example if( marks < 65 ) ++pass_count; In the above example, the variable pass_count is incremented by one only if the value of the integer variable marks is less than 65. If more than a single instruction has to be executed in case the expression is true, then the instructions are enclosed within curly brackets {}. if (marks = = 100) { cout << "mark is "; cout << marks; } In this case, two statements are to be executed if the expression in if statement is true. Hence these statements form a block and are enclosed within curly braces. The following program uses an if statement to validate the users input to be in the range 1-10.
Page 71
Unix, C & C++
#include <iostream.h> main() { int number; int valid ; cout<<"Enter a number between 1 and 10: "; cin>>number; valid = 1; if( number < 1 ) { cout<<"Number is below 1<<endl; valid = 0; } if( number > 10 ) { cout<<"Number is above 10<<endl; valid = 0; } if (valid==1) cout<<"The number is %d\n", number ; } Output: Enter a number between 1 and 10 : -78 Number is below 1. The if-else Statement The if-else is also used to carry out a logical test and then take one of the two possible actions, depending on whether the outcome is true or false. In this case it is possible to specify what has to happen if the condition is not fulfilled by using the keyword else. Its form used in conjunction with if. The general form of if-else statement is: if (expression) statement1 else statement2 Depending on whether the result of an expression is true or false, statement1 or statement2 is evaluated respectively. /* An example of the if-else statements nested in loops */ #include<iostream.h> void main() { int data;
Page 72
Unix, C & C++
cout<<Type a number between 1 and 10 :; cin>>data; if (data >=1&&data<=10) { cout<<"Data is between 1 and 10"; } else
{
cout<<"Data is not between 1 and 10"; } /* end of if else statement */ } Output: Type a number between 1 and 10: 11 Data is not between 1 and 10 Consider the if statement in the above example. It starts with the keyword if followed by an expression in parentheses. If the expression is evaluated and found to be true, the single statement following the if is executed and if the expression is false, the statement following if is skipped and the statement following else is executed. The single statement can be replaced by a compound statement composed of several statements bounded by braces. The expression "data>=1&&data<=10" is simply checking if the value of data lies between 1 and 10. The if-else structures can be concatenated with the intention of verifying a range of values. The following example shows its use telling if the present value stored in x is positive, negative or none of the previous, that is to say, equal to zero. #include<iostream.h> void main() { int x; cout<< Enter value for x :<<endl; cin>>x; if (x > 0) cout << "x is Positive"; else if (x < 0) cout << "x is Negative"; else cout << "x is Zero"; } Output: Enter value for x:
Page 73
Unix, C & C++
-4 x is Negative The switch case Statement The switch case statement is a better way of writing a program when a series of if-else occurs. The main objective of switch case statement is to check several possible constant values for an expression. The general format for this is, switch ( expression ) { case value1: program statement; program statement; ...... break; case value N: program statement; ....... break; default: ....... ....... break; } The keyword break must be included at the end of each case statement. The default clause is optional and is executed if the cases are not met. The right brace at the end signifies the end of the case selections. Rules for switch statement Values for case must be integer or character constants The order of the case statements is unimportant The default clause may occur first (convention places default last) One cannot use expressions or ranges
#include <iostream.h> main() { int menu, numb1, numb2, total; cout<<"Enter two numbers: "; cin>>numb1>>numb2 ; cout<<"Enter the choice<<endl; cout<<"1=Addition"<<endl; cout<<"2=Subtraction"<<endl; cin>>menu ; switch( menu ) { case 1: total = numb1 + numb2; Page 74
Unix, C & C++
break; case 2: total = numb1 - numb2; break; default: cout<<"Invalid option selected"; } if( menu == 1 ) cout<<numb1<<+<< numb2<<=<< total; else if( menu == 2 ) cout<<numb1<< - << numb2<< =<< total ; } Output: Enter two numbers: 37 23 Enter the choice 1=Addition 2=Subtraction 2 37 - 23 = 14 The above program uses a switch statement to validate and select upon the users input choice, simulating a simple menu of choices. Notice the inclusion of the break instructions at the end of each block. This is necessary because, if break is not included after the block of instructions pertaining to case-1, the program would not jump to the end of the switch selective block (}) and it would follow executing the rest of blocks of instructions until the first appearance of the break instruction or the end of the switch selective block.
Loops
Loops are used for executing certain set of statements repeatedly for certain number of times or until certain condition is true. There are three types of loops namely The while Loop The dowhile Loop The for Loop The while Loop The while loop continues to execute all the statements enclosed in a while block repeatedly as long as the expression in the while is true. When the condition becomes false, the looping is discontinued. The general format of this is: while (expression) statement and its function is simply to repeat statement while expression is true. If more than one statement has to be repeated, enclose them within braces.
Page 75
Unix, C & C++
/* This is an example of a "while" loop */ #include <iostream.h> void main() { int count; count = 0; while (count < 6) { cout<< The value of count is : << count<<endl; count = count + 1; } } Output: The value of count is: 0 The value of count is: 1 The value of count is: 2 The value of count is: 3 The value of count is: 4 The value of count is: 5 The above program defines an integer variable named count within the body of the program. The variable is set to zero and the program enters the while loop. As long as the expression in the parenthesis is true, all statements within the braces will be repeatedly executed. In this case, since the variable count is incremented by one every time the statements are executed, it will eventually reach 6. When the variable count becomes 6, the statement will not be executed because count is not less than 6 and the loop will be terminated. Several things must be pointed out regarding the while loop. First, if the variable count were initially set to any number greater than 5, the statements within the loop would not be executed at all, so it is possible to have a while loop that is never executed. Secondly, if the variable were not incremented in the loop, then in this case, the loop would never terminate and the program would never be completed. Finally, if there is only one statement to be executed within the loop, it does not need delimiting braces but can stand-alone. The do-while Loop
Page 76
Unix, C & C++
In the while loop the condition is checked first and if it is true the statements within the braces are executed until the condition becomes false. Some times it may be needed that the statements must be executed before the condition is checked. Thats exactly what do-while loop does. The general format is: do statement while (condition); Its functionality is exactly the same as the while loop except that condition in the do-while is evaluated after the execution of statement instead of before, granting at least one execution of statement even if the condition is never fulfilled. Consider the following example to understand do-while construct. /* This is an example of a do-while loop */ #include<iostream.h> void main() { int i; i = 0; do { cout<<"The value of i is now : "<< i<<endl; i = i + 1; } while (i < 5); } Output: The value of i is now: 0 The value of i is now: 1 The value of i is now: 2 The value of i is now: 3 The value of i is now: 4 This program is nearly identical to the last one except that the loop begins with the keyword do, followed by a compound statement in braces, then the keyword while, and finally an expression in parentheses. The statements in the braces are executed repeatedly as long as the expression in parentheses is true. When the expression in parentheses becomes false, execution is terminated and control passes to the statements following this statement. Several things must be pointed out regarding the do-while loop. Since the test is done at the end of the loop, the statements in the braces will always be executed at least once. Secondly, if the variables were not changed within the loop, the loop would never terminate, and hence the program would never terminate.
Page 77
Unix, C & C++
The for Loop The for loop is used to repeat statements while condition remains true, like the while loop. But in addition, for provides places to specify an initialization instruction and an increment instruction. So this loop is specially designed to perform a repetitive action with a counter. The general format is: for (initialization; condition; increment) statement It works in the following way: 1. Initialization is executed where the counter variable is assigned an initial value. This is executed only once. 2. Condition is checked, if it is true the loop continues, otherwise the loop terminates and statement is skipped. 3. Statement is executed. As usual, it can be either a single instruction or a block of instructions enclosed within curly brackets { }. 4. Finally, whatever is specified in the increment expression is executed and the loop gets back to step 2. The following example illustrates the use of for loop. /* This is an example of a for loop */ #include<iostream.h> void main() { int index; for(index = 0 ; index < 6 ; index = index + 1) cout<<"The value of the index is: "<< index<<endl; } Output: The value of the index is: 0 The value of the index is: 1 The value of the index is: 2 The value of the index is: 3 The value of the index is: 4 The value of the index is: 5 The for loop consists of the keyword for, followed by a rather large expression in parentheses. This expression consists of three fields separated by semi-colons. The first field contains the expression "index = 0" and is an initializing field. Any expressions in this field are executed prior to the first pass through the loop. There is essentially no limit as to what can go here, but good programming practice would require it to be kept simple. The second field, in this case containing "index < 6", is the condition which is
Page 78
Unix, C & C++
tested at the beginning of each pass through the loop. It can be any expression which will evaluate to a true or false. The expression contained in the third field is executed each time but it is not executed until after those statements in the main body of the loop are executed. This field, like the first, can also be composed of several operations separated by commas. The while loop can be used conveniently when the number of times the loop has to execute is not known and the for loop is usually used in those cases while doing a fixed number of iterations. The for loop is also convenient because it moves all of the control information for a loop into one place, between the parentheses, rather than at both ends of the code. It is upto the user to decide the type of loop to be used in the program. The Break and Continue Statements Sometimes, it may be necessary to interrupt the normal flow in the loop and come out prematurely. The branching out of loop is carried out by break and continue statements. The break statement enables the program to leave a loop even if the condition for its end is not fulfilled. It can be used to end an infinite loop or to force it to end before its natural end. The continue instruction causes the program to skip the rest of the loop in the present iteration as if the end of the statement block would have been reached, causing it to jump to the following iteration. /* This file demonstrates the use of break and continue */ #include<iostream.h> void main() { int xx; for(xx = 5 ; xx < 15 ; xx = xx + 1) { if (xx == 8) break; cout<< In the break loop, xx is now: << xx<<endl; } for(xx = 5 ; xx < 15 ; xx = xx + 1) { if (xx == 8) continue; cout<< In the continue loop, xx is now:<< xx<<endl; } } Output:
Page 79
Unix, C & C++
In the break loop, xx is now: 5 In the break loop, xx is now: 6 In the break loop, xx is now: 7 In the continue loop, xx is now: 5 In the continue loop, xx is now: 6 In the continue loop, xx is now: 7 In the continue loop, xx is now: 9 In the continue loop, xx is now: 10 In the continue loop, xx is now: 11 In the continue loop, xx is now: 12 In the continue loop, xx is now: 13 In the continue loop, xx is now: 14 Notice that in the first for loop, there is an if statement that calls a break if xx equals [Link] break will jump out of the loop and begin executing statements following the loop, effectively terminating the loop. This is a valuable statement whenever it is required to jump out of a loop depending on the value of some results calculated in the loop. In this case, when xx reaches the value of 8, the loop is terminated and the last value printed will be the previous value, namely 7. The break always jumps out of the loop just past the terminating brace. The next for loop, contains a continue statement which does not cause termination of the loop but jumps out of the present iteration. When the value of xx reaches 8 in this case, the program will jump to the end of the loop and continue executing the loop, effectively eliminating the cout statement during the pass through the loop when xx is eight. The continue statement always jumps to the end of the loop just prior to the terminating brace. At that time the loop is terminated or continues based on the result of the loop test. The goto Statement The goto statement allows making an absolute jump to another point in the program. To use a goto statement, the reserved word goto should be followed by the symbolic name, placed elsewhere in the program followed by a colon. Execution of a goto statement followed by a symbolic name will make the program jump to that particular position where that symbolic name is placed followed by a colon. Jumping can be nearly anywhere within a function, but jump into a loop is not permitted, although jumping out of a loop is allowed. #include<iostream.h> void main() { int i,j,k; for(i=0;i<20;i++) { for(j=0;j<20;j++) { Page 80
Unix, C & C++
for(k=0;k<20;k++) { if (i==j) goto flag3; } cout<< One; } } flag3: cout<<I am out of the loop!; } Output: I am out of the loop! However the use of goto is not a good programming style. Of course, at some places it can come quite handy. 4.2.6 Defining Classes and Objects
A class is like a template from which objects can be created. Now what is an object? It is an abstract concept and one cannot exactly define an object. An object, however can be described by its behavior, state and identity. Every object will have a state, an unique behavior and an identity. Class definition The class definition consists of the keyword class, the name of the class, an opening brace, a closing brace, and a semicolon: class Test { }; keyword class and class name opening brace other programming lines to go here closing brace and semicolon
The braces (sometimes called curly brackets) are delimiters. They enclose the body of the class specification so that one (and the C++ compiler) can see where exactly the class begin and end. Example class class_name { private: variable declarations; variable declarations; public: variable declarations; Page 81 function declarations; };
Unix, C & C++
The keyword class specifies an abstract data of type class_name. The body of a class is enclosed within braces and terminated by a semicolon. The class body contains the declarations of variable and functions. These functions and variables are collectively called members. They are usually declared under two sections namely, private and public to denote which of the members are private and which of them are public. The members that have been declared as private can be accessed only from within the class. On the other hand, public members can be accessed from outside the class also. The data hiding (using private declaration) is the key of object-oriented programming. The use of the private keyword is optional. By default, the members are private. The variables declared inside the class are known as data members and the functions are known as member functions. Only the member functions can have access to the private data members and private [Link], the public members(both functions and data) can be accessed from outside the class. The binding of the data and function together into a single class-type variable is referred to as encapsulation Class members A class is made up of variables and functions. These are called the members of the [Link] variables of the class provide the state to the object while functions of a class provide the behavior to the given class. Member functions The member functions have a very important role to play as they define how an object will behave. Typically a program calls an objects member function to tell the object to do something. This is why calling an objects member function is also called sending a message to the object. Functions are expressions that execute an operation, allowing a programmer to create several pieces of code and bunch them together to perform a particular task. Functions accept information in the form of arguments and evaluate the arguments to provide the result. Example int print( int x, int y) { int z=x+y; return z; } Objects
Page 82
Unix, C & C++
In C++, an object is a region of storage with associated semantics. The declaration int i, specifies that i is an object of type int. In the context of the object model of C++, the term object refers to an instance of a class. Thus a class defines the behavior of possibly many objects (instances). Objects are usually referred to by references, which are aliases for an object. A C++ class definition generates a user-defined type. A class defines the characteristics of its instances in terms of members- data members (state) and member functions (methods or operations) and the visibility of these members to other classes. The class defines the form of all objects that belong to that class. Each object of the class that is created gets a copy of all the class data members, except for those declared as static. All objects of a particular class share the member functions for that class. Access Specifiers The access specifier specifies the accessibility of the class members. It decides the scope of the members of the class, thereby allowing certain members to be accessed only inside the class while certain members of the class are allowed to be accessed from outside the class also. There are different types of access specifiers namely: private, public and protected. Private: Members are accessible only to members of that class. Protected: Members are accessible from members of its derived classes and from members of the same class. Public: Members are accessible from anywhere where the class is visible. The access specifier is optional. A class can also be defined without using any access specifier. In such case, the members of the class are not accessible outside the class. This means that the members of the class become private. The scope of any member of a class can be changed by using the corresponding access specifier before it. This will change the scope of all the members following it. If the scope of one of them has to be changed once again the required access specifier is used before it. Example #include<iostream.h> class Sample { public: void show() { cout<< Simple Function ; } }; main() { Sample ss;
Page 83
Unix, C & C++
ss. show(); } Output: Simple Function Array of Objects One can declare arrays of variables that are of the type class. Such variables are called arrays of objects. Consider the following class definition: class employee { char name[30]; int age; public: void getdata(void); void putdata(void); }; The identifier employee is a user-defined data type and can be used to create objects that relate to different categories of the employees. Example employee manager [3]; // array of manager employee foreman [5]; // array of foreman employee worker [75]; // array of worker The array manager contains three objects (managers), namely, manager[0], manager[1] and manager[2], of type employee class. Similarly, the foreman array contains 5 objects(foreman) and worker array contains 75 objects (workers). Since an array of objects behaves like any other array, one can use the usual array-accessing methods to access individual elements and then the dot member operator to access the member functions. For example, the statement manager[i].putdata(); will display the data of the i th element of the array manager. That is, this statement request the object manager[i] to invoke the member function putdata(). Example #include<iostream.h> class employee { private: char name[30]; int age; public: void getdata(void); void putdata(void); };
// a class member
Page 84
Unix, C & C++
void employee:: getdata(void) { cout << Enter name :; cin >> name ; cout << Enter age: ; cin >> age; } void employee::putdata(void) { cout << Name: << name; cout << \n Age: << age; cout << \n \n; } main() { int i; employee manager[3]; // Array of managers for ( i=0; i<3; i++) { cout << \n Details of manager << i+1 << \n; manager[i].getdata(); } cout << \n; for (i=0;i<3;i++) { cout << \n Manager << i +1 << \n; manager[i].putdata(); } } The coding for the function can be written in two different ways. One way is within the class and another way is outside the class. Since the function is defined outside the class, scope resolution operator (indicated by :: ) along with the class name is used. The scope resolution operator binds the name of the function along with the class to which it belongs; as otherwise the compiler would not know to which class that member function belongs. The class definition should finally end with a semi-colon. The above program begins an interactive program, the input data and the program output array is shown below: Interactive input: Details of manager1 Enter name:aaa Enter age:50 Details of manager2 Enter name:ccc Page 85
Unix, C & C++
Enter age:40 Details of manager3 Enter name:ddd Enter age:45 Output: Manager1 Name :aaa Age :50 Manager2 Name :bbb Age :40 Manager3 Name :ddd Age :45 Passing Objects as Functions Arguments Like any other data type, an object may be used as a function argument. This can be done in two ways: A copy of the entire object is passed to the function Only the address of the object is transferred to the function. The first method is called pass-by-value. Since a copy of the object is passed to the function, any change made to the object inside the function does not affect the original object passed as argument to that function. The second method is called passby-reference. When an address of the object is passed, the called function works directly on the actual object passed as argument in the call. This means that any changes made to the object inside the function will reflect in the actual object passed to that function. The pass-by reference method is more efficient since it requires passing only the address of the object and not the entire object. Objects can be used as a function argument in two ways: A copy of the entire object is passed to the function (pass-by-value) Example: Implemented in Operator Overloading
Only the address of the object is transferred to the function (pass-byreference) Example: Implemented in Copy Constructor 4.2.7 Functions and its Types
Page 86
Unix, C & C++
Functions play an important role in c++ program development. Dividing a program into functions is one of the major principles of top-down, structured programming. Another advantage of using functions is that it is possible to reduce the size of a program by calling and using them at different places in the program. C++ has added many new features to functions to make them reliable and flexible. Different types of functions are as follows: inline Function Constant Function Static Function inline Function Functions defined within the class are called inline functions. When a function is inline, the compiler will replace the function call with a copy of the function body instead of calling the function every time it is invoked. However all functions that is inline may not be considered inline function by the compiler. It is always a good practice to inline only those functions that has one or two statements. The following example show a class in which the functions are defined inside the class itself and these functions constitute the inline functions. #include<iostream.h> class Circle { int r; public: void input() { cout<< Enter the value of the radius: ; cin>>r; } void area() { cout<< Area=<<3.14*r*r; } }; main() { Circle c; [Link](); [Link](); } Output: Enter the value of the radius: 5 Area=78.5
Page 87
Unix, C & C++
In this program, an object of class Circle is created in the main(). The class Circle has two functions input() and area(), both defined inside the class. This means that both the functions have been declared inline (i.e., inside the class). Advantages It requires fewer keystrokes to inline a function. It is possible to speed up the program by inlining the right function. Disadvantages Since the compiler will copy the entire function body every time the function is called, if it is a large function (more than three or four lines), inline function can increase the size of the executable program significantly. Although it is sometimes easier to read functions if they are inline, it is sometimes harder to read inline functions. If a function is more than one or two lines, using the function inline will more than likely distract a reader who is trying to understand how the class works. Constant Function Constant Functions are the special kind of functions which are not allowed to change the value of the instance variables. A function is made a constant function by using the keyword const. Consider the following program: #include<iostream.h> class Circle { int r; public: void input() { cout<< Enter the value of the radius; cin>>r; } void area() const { cout<< Area=<<3.14*r*r; } }; main() { Circle c; [Link](); [Link](); } Output:
Page 88
Unix, C & C++
Enter the value of the radius12 Area=452.16 In this case the function area() is made a constant function. This means that it cannot change the value of the instance variable. Suppose a statement like r++; is included in the function area, it will result in error. This way, it can be ensured that the area of circle of given radius is only computed. The advantage of making a function constant is that, the accidental change in value of the instance variable can be avoided. Static Function Static Functions are functions that are not confined to a single object but to the class as such. In fact these functions can be called using the class name and scope resolution operator and there is no need to create an object of a class to call the static function of the class. A function is made a static function by using the keyword static. The following program creates a static function for a class and calls it without even creating the object. #include<iostream.h> class St { public: static void stat() { cout<< This is a static function<<endl; } void display() { cout<< Not a static function<<endl; } }; main() { St::stat(); //St::display(); St s; [Link](); [Link](); } Output: This is a static function This is a static function Not a static function
Page 89
Unix, C & C++
Since the function stat() in the program above, is a static function it is called even before an object could be created. Look at the second statement in the main block, this statement has been commented. This is because that statement calls the function display() directly without creating an object. This will lead to error as the function is only an ordinary function and not a static function. 4.2.8 Function Overloading
Function Overloading refers to the process of defining more than one function with the same name inside the same class. Although the name of these functions remains the same, either the number of arguments or the data type of the arguments passed to the function must differ. It is based on these distinctions that the compiler will spot the correct function. #include<iostream.h> class FuncOver { public: float avg(int , int); float avg( int, int, int); }; float FuncOver::avg(int in1, int in2) { return (in1 + in2)/2.0; } float FuncOver::avg(int in1, int in2, int in3) { return (in1 + in2 + in3)/3; } main () { FuncOver f; cout << "Average of two numbers is: " << [Link](23,25)<< endl; cout << "Average of three numbers is: " << [Link](23,25,24)<< endl; } Output: Average of two numbers is: 24 Average of three numbers is: 24 The function avg() has been overloaded in the class FuncOver. The function avg() accepts two integer arguments in one form while it accepts three integer arguments in the other form. Thus depending on whether the average of two numbers has to be computed or average of three numbers has to be computed, the corresponding function is called.
Page 90
Unix, C & C++
4.2.9 Constructors
A constructor is a special function, which is having the same name as that of the class. The constructor will be called automatically when a new instance of the class is created. The constructor also differs from the function in that it has no return type. To make obvious the concept of constructor program is as follows:
#include<iostream.h> class Rectangle { int x, y; public: Rectangle(); void area (); private: int z; }; Rectangle::Rectangle( ) { cout<< Enter x and y values <<endl ; cin>>x; cin>>y; } void Rectangle::area() { z=x*y; cout<< Area : << z; } main() { Rectangle r; [Link](); } Output: Enter x and y values 2 3 Area: 6 In this program, there is no separate function for accepting the value for the instance variables; a constructor is used instead. Hence, when the object is created as Page 91
Unix, C & C++
shown in the first statement of the main(), the constructor is called automatically. The programmer need not worry about ensuring if the functions are called in proper order. The constructor then accepts the value for the instance variables and the final output is got when the function area() is called.
Difference between Constructor and member function Constructor Member function Constructor has the same name as The name of the function can be different. that of the class. Return type is not allowed Functions have return type.
Constructor is called automatically Functions can be invoked only through objects. when an object is created. 4.2.10 Constructor Overloading Just like a function can be overloaded, the same way constructor can also be overloaded. This means that a class can have more than one constructor but the number of arguments or the data type of the arguments passed to them differs. #include<iostream.h> class Poly { int a,b,c; public: Poly() { a=0; b=0; c=0; cout<< Not a polygon<<endl; } Poly(int x) { a=x; cout<< It is a square of side << a<<endl; cout<< Perimeter of the Square :<< 4*a<<endl; } Poly(int x, int y)
Page 92
Unix, C & C++
{ a=x; b=y; cout<< It is a rectangle of height << a<< and width << b<< endl; cout<< Perimeter of the Rectangle :<< 2*(a+b)<<endl; } Poly(int x, int y, int z) { a=x; b=y; c=z; cout<< It is a Triangle << endl; cout<< Perimeter of the Triangle :<< (a + b + c)<<endl; } }; main() { Poly p1,p2(5),p3(5,3),p4(1,2,3); } Output: Not a polygon It is a square of side 5 Perimeter of the Square :20 It is a rectangle of height 5and width 3 Perimeter of the Rectangle :16 It is a Triangle Perimeter of the Triangle :6 The class Poly has four types of constructors. One of it uses no argument while the others use one, two and three arguments. Depending on the requirement, the required constructor is called by passing the corresponding number of arguments. 4.2.11 Destructors The Destructor can be considered to be the opposite of constructor functionality wise. It is automatically called when an object is released from the memory, either because it goes out of scope or because it is an object dynamically assigned and is released using operator delete. The destructor must have the same name as the class with a tilde (~) as prefix and it must return no value. The use of destructors is especially suitable when an object assigns dynamic memory during its life and at the moment of being destroyed the memory that it has used has to be released. The following program uses a destructor. The destructor is called automatically when the program terminates.
Page 93
Unix, C & C++
#include<iostream.h> class Square { int a; public: Square(); ~Square(); int peri(); }; Square::Square() { cout<< Enter the length of the side of a square <<endl; cin>>a; } int Square::peri() { int p; p=4*a; cout<< Perimeter of the square is : ; return p; } Square::~Square() { cout<< \n Destructor called :End of program; } main() { Square s; cout<<[Link](); } Output: Enter the length of the side of a square 5 Perimeter of the square is : 20 The above program uses only two statements in the main. The first statement in the main() creates an object of class Square thereby calling the constructor. This is then followed by a call to the member function peri() to compute the perimeter of the square. The program then ends calling the destructor. Difference between Constructor and Destructor Constructor Destructor
Page 94
Unix, C & C++
Constructor has the same name as It has the same name as that of the class but the that of the class. name is preceded by a tilde (~) symbol Constructor is called automatically when an object is created. Destructor is called automatically when the object goes out of scope.
4.2.12 Dynamic initialization of objects Class objects can be initialized dynamically too. That is, the initial values for the objects data member may be provided during run time. One advantage of dynamic initialization is that various initialization formats can be provided, using overloaded constructors. This provides the flexibility of using different format of data at run time depending upon the situation. Consider the long-term deposit schemes working in the commercial banks. The banks provide different interest rates for different schemes as well as for different periods of investment. The Program below illustrates how to use the class variables for holding account details and how to construct these variables at run time using dynamic initialization. #include<iostream.h> class Fixed_deposit { long int P_amount; //Principal amount int Years; //Period of investment float Rate; //Interest rate; float R_value; //Return value of amount public: Fixed_deposit(){} Fixed_deposit(long int p, int y, float r); Fixed_deposit(long int p, int y); void display(void); }; Fixed_deposit :: Fixed_deposit(long int p, int y) { float r=0.21; P_amount=p; Years =y; Rate =r; R_value=P_amount; for(int i=1;i<=y; i++) R_value =R_value * (1.0 +r); } Fixed_deposit :: Fixed_deposit(long int p, int y, float r) { Page 95
Unix, C & C++
P_amount=p; Years =y; Rate =r; R_value=P_amount; for(int i=1;i<=y; i++) R_value =R_value * (1.0 +float (r)/100); } void Fixed_deposit ::display (void) { cout << \n; cout << Principal Amount = << P_amount << \n; cout << Return Value = << R_value << \n; } main() { Fixed_deposit FD1, FD2,FD3; //deposit created long int p; //principal amount int y; //investment period, years float r; //interest rate, decimal form int R; //interest rate, percent form cout << Enter amount, period, interest rate(in percent) << \n; cin >> p >> y >>R; FD1=Fixed_deposit(p,y,R); cout << Enter amount, period, interest rate(decimal percent) << \n; cin >> p >> y >>r; FD2 =Fixed_deposit(p,y,r); cout << Enter amount and period << \n; cin >> p >> y; FD3 =Fixed_deposit(p,y); cout << \n Deposit 1; [Link](); cout << \n Deposit 2; [Link](); cout << \n Deposit 3; [Link](); } Output: Enter amount,period,interest rate(in percent) 5000 5 15
Page 96
Unix, C & C++
Enter amount,period,interest rate(in decimal form) 5000 5 0.15 Enter amount and period 5000 5 Deposit 1 Principal Amount =5000 Return Value=10056.8 Deposit 2 Principal Amount =5000 Return Value=5037.61 Deposit 3 Principal Amount =5000 Return Value=12968.7 The program uses three overloaded constructors. The parameter values to these constructors are provided at run time. The user can provide input in one of the following forms: 1. Amount, period and interest in decimal form. 2. Amount, period and interest in percent form. 3. Amount and period. Since the constructors are overloaded with the appropriate parameters, the one that matches the input values is invoked. For example, the second constructor is invoked for the forms(1) and (2), and the third is invoked for the form(3). Note that, for form(3),the constructor with default argument is used. Since input to the third parameter is missing, it uses the default value for r. 4.2.13 Copy Constructor Copy constructor is a special type of constructor in C++. The functionality of copy constructor is similar to copying variables. Copying variables For Example, int a = 10; int b=20; With basic data types copying means creating a new variable of the same type and giving it the same value. The above statement does not mean assigning a value to an existing variable, they mean initializing variable. A different notation can be used for copying one variable to another. For Example, instead of int a=b;
Page 97
Unix, C & C++
This type of notation is sometimes called as functional notation. Anyhow to avoid confusion the equal sign can be used in between. In the similar way objects can also be copied. Functional notation is widely used in Copy Constructors. Copy constructors provide another way to create objects, by making a copy of an existing object. They take a unique argument type. Example #include<iostream.h> class CopyCon { private: int intvar; public: CopyCon() { intvar = 10; } CopyCon(int v) { intvar=v; } CopyCon(CopyCon &obj) { intvar = [Link]; cout << "I am a copy constructor \n" ; cout << "intvar value inside copy constructor is " << intvar << endl; } void disp() { cout << "Value of intvar is " << intvar << endl; } }; void main() { CopyCon cobj; CopyCon cobj1(27); CopyCon cobj2 = cobj1; CopyCon cobj3(cobj1); [Link](); [Link](); [Link](); Page 98
Unix, C & C++
[Link](); } Output: I am a copy constructor intvar value inside copy constructor is 27 Iam a copy constructor intvar value inside copy constructor is 27 Value of intvar is 10 Value of intvar is 27 Value of intvar is 27 Value of intvar is 27 4.2.14 Friend Function So far, it has been stated that the private members of a class are not accessible anywhere outside the class. But these private members of a class are accessible to a function declared to be a friend of that class. Thus a friend function of a class is that function that has access to even the private members of the class. A function is declared a friend function by using the keyword friend. #include<iostream.h> class Rectangle { int width, height; public: Rectangle(); int area () ; friend void perimeter (); }; int Rectangle::area () { return (width * height); } Rectangle::Rectangle () { cout<<Enter the width and height values: <<endl; cin>>width; cin>>height; } void perimeter () { Rectangle r; int p; p=2*([Link] + [Link]); Page 99
Unix, C & C++
cout<< The perimeter of Rectangle is: << p; } main () { perimeter(); } Output: Enter the width and height values: 5 4 The perimeter of Rectangle is: 18 The program above illustrates the use of a friend function. In this case, the function perimeter() is a friend function of the class Rectangle and hence can gain access to the private members of the class Rectangle. 4.2.15 Operator Overloading C++ has an important concept of Operator Overloading. Operator Overloading is a special case of function overloading, which allows assigning additional meanings to most of the standard C++ operators. When overloading operators, it is a good practice to ensure that the overloaded operator has a similar behaviour to the original operator. For example, it would make more sense to use the + operator for concatenation of strings than the = operator. Overloading operators does not change the precedence and associativity of the operator. New operators cannot be introduced using operator overloading. An operator is overloaded using the keyword operator. The general syntax for overloading an operator is as follows: return_type operator operatorsymbol(argument) { statement; } where, return_type: refers to the data type of the variable or object to which the call to the overloaded operator is assigned. If the overloaded operator is not assigned to anything its return type is void. operator is a keyword. operatorsymbol refers to the operator that is to be overloaded.
Page 100
Unix, C & C++
argument refers to the variable or object that is used along with the operator. There should be a single argument in case of overloading a binary operator and there should be no argument when overloading unary operator. An overloaded operator is called by giving the name of the object followed by the overloaded operator as follows: Object_name overloaded_operator Unary Operator Overloading The following example shows how a unary operator is overloaded. The program uses the increment operator ++. This operator requires only a single operand and hence takes no argument when it is overloaded. #include<iostream.h> class Uno { int a; public: Uno() { a=1; } void operator ++() { a++; } int display() { return a; } }; main() { Uno u; cout<< Initial Value of a : <<[Link]()<<endl; ++u; cout<< Final Value of a : <<[Link](); } Output: Initial Value of a :1 Final Value of a :2 The class Uno has a single instance variable a. Inside the overloaded operator function, the value of the instance variable is incremented. Hence when the function ++ is
Page 101
Unix, C & C++
called using the object u, the instance variable a of object u is incremented and the incremented value of a is then displayed when the function display() is called. Binary Operator Overloading The following program shows overloading of binary operator +. This operator takes a single argument. #include<iostream.h> class Bi { int x,y; public: Bi() { x=1; y=2; } Bi operator +(Bi b1) { Bi b2; b2.x=x+b1.x; b2.y=y+b1.y; return b2; } void display() { cout << x:<<x<<endl<< y: <<y<<endl; } }; main() { Bi u,v,z; cout<< Initial Values:- ; [Link](); [Link](); [Link](); u=v+z; cout<< Final Values:- ; [Link](); [Link](); [Link](); } Output:
Page 102
Unix, C & C++
Initial Values:- x:1 y:2 x:1 y:2 x:1 y:2 Final Values:- x:2 y:4 x:1 y:2 x:1 y:2 This program creates three objects of class Bi. Each time the constructor is called and the instance variables x and y of each of the object are assigned a value of 1 and 2 respectively. This is evident when the function display() of the class Bi is called using each of these objects. Note the statement, u=v+z; Here, the object v calls the overloaded operator +. Hence the variables x and y referred inside the function denotes the instance variable of the object v. The statement also shows that an object z is also used along with the overloaded operator + on the right hand side. This object is passed as an argument to the overloaded operator function +. Thus the values of the instance variable of the object z are copied to the instance variable of object b1. Thus the value of b1.x is same as that of z.x and the value of b1.y is same as that of z.y. Inside the overloaded operator function another object of class Bi called b2 is created. The instance variable x of the object b2, that is, b2.x is assigned the sum of v.x and b1.x (same as z.x). Similarly the instance variable y of the object b2, that is, b2.y is assigned the sum of v.y and b1.y (same as z.y). The object b2 is finally returned from the function and hence the value of instance variables of this object are assigned to the corresponding instance variable of the object u. General Rules for Overloading Operators There are certain restrictions and limitations to be kept in mind while overloading operators. The rules are: Only existing operators can be overloaded. New operators cannot be created. It is recommended not to change the basic meaning of an operator. That is, the plus (+) operator should not be redefined to subtract one value from another. Overloaded operators follow syntax rules of the original operators that cannot be overridden. Friend functions cannot be used to overload certain operators like =, (), [] and ->.
Page 103
Unix, C & C++
Unary operators, overloaded by means of a member function take no explicit arguments. But those overloaded by a friend function take one reference argument. Binary operator overloaded through a member function takes one explicit argument and those that are overloaded through a friend function take two arguments. Binary operators such as +, -, * and / must explicitly return a value. When using binary operators overloaded through a member function, the left hand operand must be an object of the relevant class.
Operator Overloading Restriction There are some restrictions that apply to operator overloading. Operator functions cannot have default arguments. The operators that cannot be overloaded are: . :: . * ?: sizeof One cannot alter the precedence of an operator. One cannot change the number of operands that an operator takes.
4.2.16 Type Conversions Type conversion means converting a value in one data type to another. This is necessary so that a value of one data type can be conveniently assigned to a variable of a different data type. Argument type conversion During the function overload resolution, the compiler identifies and ranks the conversions that can apply to each argument in a function call to convert it to the type of the corresponding parameter in each viable function. There are three possible outcomes of this ranking: 1. An exact match. The argument matches the type of the function parameter exactly. 2. Match with a type conversion. The argument does not directly match the type of the parameter but can be converted to the destination type. 3. No match. The argument cannot be made to match a parameter of the declared functions, because no type conversions exist between the argument and the corresponding function parameter.
Page 104
Unix, C & C++
When selecting the best viable function for a function call, the compiler selects the function for which the type conversions on the arguments are the best. Type conversions are ranked as follows: an exact match is better than a promotion, a promotion is better than a standard conversion, and a standard conversion, and a standard conversion is better than a user-defined conversion. Promotion Conversion A promotion conversion is one of the following: An argument of type char, unsigned char, or short is promoted to type int. An argument of the type unassigned short is promoted to type int if the machine size of an int is larger than that of shorter integer otherwise, it is promoted to type unsigned int. An argument of type float is promoted to type double. An argument of an enumeration type is promoted to the first of the following type that can represent all the values of the enumeration constants: int, unsigned int or unsigned long. An argument of type bool is promoted to type int.
Standard Conversion There are five kinds of conversions grouped in the category of standard conversions: 1. The integral conversions: the conversions from any integral type or enumeration type to any other integral type. 2. The floating point conversions: the conversions from any floating point type to any other floating point type. 3. The floating integral conversions: the conversions from any floating point to any integral type or vice versa. 4. The pointer conversions: the conversion of a pointer of any type to the type void. 5. The bool conversions: the conversions from any integral type, floating point type, enumeration type, pointer type to the type bool. User Defined Conversion (Casting operators &Conversion functions) When the value of one object is assigned to another of the same type, such as dist3 = dist1 + dist2; the values of all the member data items are simply copied into the new object. The compiler knows how to do this automatically. Data conversion occurs when one type of data is assigned to another of different type. The conversion can be implicit such as
Page 105
Unix, C & C++
intvar = floatvar; Casting provides explicit conversion: intvar = static_cast<int>(floatvar); For conversion of user-defined types, the programmers must define the conversion routines. Data conversion may seem unnecessarily complex or even dangerous. However, the flexibility provided by allowing conversions outweighs the dangers. Conversions between Objects and Basic Types The following example performs the data conversion between the objects of class distance and float. The conversion is meant to convert Distance into meter and vice versa. # include <iostream.h> const float MTF = 3.280833F; class Distance { private: int feet; float inches; public: Distance() { feet=0; inches=0.0; } Distance(float meters) { float fltfeet = MTF * meters; feet = int(fltfeet); inches = 12*(fltfeet-feet); } Distance(int ft, float in) { feet =ft; inches = in; } void getdist() { Page 106
Unix, C & C++
cout << "\nEnter feet: "; cin >> feet; cout << "Enter inches: "; cin >> inches; } void showdist() const //display distance { cout << feet << "\'-" << inches << '\"' ; } operator float() const //conversion operator { float fracfeet = inches/12; fracfeet += float(feet); return fracfeet/MTF; } }; void main() { float mtrs; Distance dist1 = 2.35F; cout << "\ndist1 = "; [Link](); dist1 = 1.00; cout << "\ndist1 = "; [Link](); Distance dist2(5, 10.25); mtrs = float(dist2); cout << "\ndist2 = " << mtrs << " meters\n"; mtrs = dist1; cout << " \n dist1 = " << mtrs << "meters" ; } Output: dist1 = 7'-8.51949" dist1 = 3'-3.37" dist2 = 1.78435 meters dist1 = 1meters
4.3
Revision Points
Object-oriented programming Object-oriented programming attempts to respond to these needs, providing techniques for managing enormous complexity, achieving reuse of software components, and coupling data with the tasks that manipulate that data. The essence of object-oriented programming is to treat data and the procedures that act upon the data as a single "object". An Object is a self-contained entity with an identity and certain characteristics of its own.
Page 107
Unix, C & C++
Object Object may represent a person, a place, a bank account, a table of data or any item that the program must handle. When a program is executed, the objects interact by sending messages to one another. Class A class is a collection of similar objects. Encapsulation The winding up of data and function into a single unit (called class) is known as encapsulation. Data encapsulation is the most striking feature of class. Inheritance Inheritance is the process by which objects of one class acquire the properties of another class. Polymorphism Polymorphism plays an important role in allowing objects having different internal structures to share the same external interface. This means that a general class of operations may be accessed in the same manner even though a specific action associated with each operation may differ. Polymorphism is extensively used in implementing inheritance. Inline function Functions defined within the class are called inline functions. When a function is inline, the compiler will replace the function call with a copy of the function body instead of calling the function every time it is invoked. Constant Function Constant Functions are the special kind of functions which are not allowed to change the value of the instance variables. A function is made a constant function by using the keyword const. Static Function Static Functions are functions that are not confined to a single object but to the class as such. In fact these functions can be called using the class name and scope resolution operator and there is no need to create an object of a class to call the static function of the class. A function is made a static function by using the keyword static. Function Overloading Function Overloading refers to the process of defining more than one function with the same name inside the same class. Although the name of these functions remains the same, either the number of arguments or the data type of the arguments passed to the function must differ.
Page 108
Unix, C & C++
Constructor A constructor is a special function, which is having the same name as that of the class. The constructor will be called automatically when a new instance of the class is created. Destructor The Destructor can be considered to be the opposite of constructor functionality wise. It is automatically called when an object is released from the memory, either because it goes out of scope or because it is an object dynamically assigned and is released using operator delete. Operator Overloading Operator Overloading is a special case of function overloading, which allows assigning additional meanings to most of the standard C++ operators.
4.4
Intext Questions
1. What is OOPs? What is the significance of OOPs? 2. Explain the features of OOPs. 3. Define the following terms: Variable. Keyword. Data type. Constant. 4. What is inheritance? Why you need inheritance? 5. When will you make a function inline? Why? 6. When do you need to use constant function? 7. Explain the merits and demerits of inline function. 8. Describe the importance of constructor. 9. Explain copy constructor with an example. 10. Explain type conversion with an example. 11. Which operator cannot be overloaded?
4.5
Summary
OOP is used to decompose a problem into a number of entities called objects. A class is a way of creating user-defined data types. A class declaration consists of data member and member functions.
Page 109
Unix, C & C++
An object is an instance of a class. Inheritance is the process by which objects of one class acquire the properties of another class. Polymorphism means the ability to take more than one form. Objects communicate with one another by sending and receiving information in the same way as people pass message to one another. C++ has three different types of access specifiers namely: private, public and protected. In C++, the main() returns a value type int to the operating system. Variables are quantities whose values can be changed. Constants are quantities whose values cannot be changed. Data type decides the type of value, a variable can hold. Keywords are special words that have a specific meaning in a computer language. Any program will start its execution from the main() function. C++ handles data input and output using cin and cout statements respectively. C++ supports the concept of comments which are text that give information to the user about what a particular statement does in a program. Operators are symbols that manipulate the data, which constitute the operand. Every operator has two important properties called precedence and associativity. Operators are classified into unary and binary operators depending on the number of operands. A comment is just some text enclosed in a pair of comment delimiters. A function is made a constant function by using the keyword const.
Page 110
Unix, C & C++
A function is made a static function by using the keyword static. Function Overloading refers to the process of defining more than one function with the same name inside the same class. A constructor is a special function, which is having the same name as that of the class. The Destructor can be automatically called when an object is released from the memory. Advantage of dynamic initialization is that one can provide various initialization formats, using overloaded constructors. A friend function of a class is that function that has access to even the private members of the class. Operator Overloading is a special case of function overloading, which allows assigning additional meanings to most of the standard C++ operators. An operator is overloaded using the keyword operator. The operators that cannot be overloaded are: . ,::, .*,?: and sizeof. Type conversion means converting a value in one data type to another.
4.6
Terminal Exercises
1. 2. 3. 4. 5. 6. 7. Explain static function with example. What is the need for overloading an operator? How do we invoke a constructor and destructor function? Constructors do not return any values (True/False). What do you mean by function overloading? When do we use this concept? What is friend function? Define operator overloading.
4.7
Supplementary Materials
1. 2. Schildt, C++: The Complete Reference, Third Edition, TMH, 2000. [Link], C++, Second Edition, TMH, 2001.
Page 111
Unix, C & C++
4.8
Assignments
1. What are objects? Describe the syntax for defining objects with examples. Explain how C++ supports encapsulation and data abstraction. 2. Write a program illustrating class declaration, definition, and accessing class members. 3. Write a note on different types of operators used in C++. 4. List the operators that cannot be overloaded and justify why they cannot be overloaded. 5. Write a program that accepts 2 numbers and find their sum and difference. 6. Write a program that accepts 2 numbers from the user and print their product.
4.9
Suggested Reading/Reference Books/Set Books
1. [Link], [Link], The Programming Language, PHI, 1988 2. Venugopal, Rajkumar, Ravishankar, Mastering C++, TMH, 2001.
4.10 Learning Activities
1. Collect information on Object Oriented Programming concepts from the internet. 2. Collect information on Type conversion.
4.11 Keywords
Object Oriented Programming (OOP) Object Polymorphism Abstraction Destructor Friend function Class Inheritance Encapsulation Constructor Copy Constructor Operator Overloading
Page 112
Unix, C & C++
Page 113