INFORMATION FROM DR. EBRAHIMI'S C++ PROGRAMING EASY WAYS

Home                  ABOUT US                    CONTACT US                  TUTORIAL

CHAPTER 15

 

POLYMORPHISM, TEMPLATE, AND ADT

 

 

Polymorphism consists of two words: poly, which means “many,” and morph, which means “form.” In programming, polymorphism is the ability to have many forms for the same name.  An example of polymorphism is when different functions do a similar task and have the same function name or similarly when using many forms for the same operator. Polymorphism, encapsulation, and inheritance are three important features of object-oriented programming. Function overloading and operator overloading are two examples of polymorphism. A user function or a built-in operator can be overloaded while performing what it was originally designated to do. A computer teacher can become overloaded by teaching an additional math or other course. One form of polymorphism is function overloading. For example, the same function name:  print( ) prints the list of items in a queue or a stack, regardless if they were created statically or dynamically. Another example of polymorphism is operator overloading which adds a new meaning to most of the C++ operators. C++ operators are defined for the basic data types; with operation overloading, the same operators can be applied to user-defined types, keeping the operation in the same form as it is applied to the basic types. The goal of operator overloading is to allow user defined types (classes) to behave in the same way as built-in types.  Polymorphism contributes to the concept of abstraction by providing a meaningful name that can be used differently for several similar functions and operations. Therefore, a programmer can focus on the function’s and operator’s work rather than getting involved in the overwhelming details of the implementation. As long as the same interface is exposed, the implementation is irrelevant. Finally, for a language to be considered an object-programming language, it must support the features of polymorphism. C++ templates allow programmers to code and reuse code regardless of the specific data type. When the type of data is defined, the compiler will generate the code as if it was written for that specific data type.

 

 

FUNCTION OVERLOADING

 

A function is overloaded when the same function name is used to perform different tasks depending on the data type. Function overloading is one of the simplest forms of polymorphism. In the following program, there are three versions of findsmaller( ); each version of the function takes and returns a different data type. The function findsmaller( ) is referred to as an overloaded function. Without the use of function overloading, the same program would require three different function names to perform the same task.

 

 

 

 

 

 

 

Text Box: #include<iostream>
using namespace std;
int findsmaller(int x, int y){ if(x<y) return x;  else return y; }
double findsmaller(double x, double y){ if(x<y) return x; else return y; }
char findsmaller(char x, char y){ if(x<y) return x; else return y; }
int main(){
            int a,b;   double c,d;   char e,f;
            cout<<"ENTER TWO INTEGER VALUES: ";      
cin>>a>>b;
            cout<<"ENTER TWO DOUBLE VALUES: ";       
cin>>c>>d;
            cout<<"ENTER TWO CHARACTER VALUES: ";   
cin>>e>>f;
            cout<<"THE SMALLER OF TWO INTEGERS IS: "<<findsmaller(a,b)<<endl;
            cout<<"THE SMALLER OF TWO DOUBLES IS: "<<findsmaller(c,d)<<endl;
            cout<<"THE SMALLER OF TWO CHARACTERS IS: "<<findsmaller(e,f)<<endl;  
return 0;
}//MAIN
 

  

 

 

 

 

 

 


 

               

 

 

 

 

 

Text Box: Figure 15-1a  – Example of function overloading
 

  

 

 

Text Box: ENTER TWO INTEGER VALUES: 9 10
ENTER TWO DOUBLE VALUES: 5.50 7.75
ENTER TWO CHARACTER VALUES: a z
THE SMALLER OF TWO INTEGERS IS: 9
THE SMALLER OF TWO DOUBLES IS: 5.5
THE SMALLER OF TWO CHARACTERS IS: a

  

 

 

 

 

 

 

 

 

Text Box: Figure 15.1b – Output of 15.1a

  

 

 

 

 


 

HOW DOES FUNCTION OVERLOADING WORK: FUNCTION SIGNATURE

 

How does the compiler determine which function to call when there are several functions with the same name? A C++ complier uses the function’s signature to determine which function to call. A function’s signature consists of the function name and the parameter (argument) list. Note that in the function’s signature, the return type is not needed because it is necessary in the function’s prototype. If there is not an exact match in the argument list, the C++ compiler tries to use a standard type conversion such as converting an integer to a double if necessary. The following program swaps different data types; the compiler is able to figure out the correct function call by using the actual types from the arguments. The number of the arguments and their type may vary in each function.

 

 

 

 

Text Box: #include<iostream>
#include<string.h>
using namespace std;
void swap(char * str1, char * str2){ 
            char temp[80];
            strcpy(temp,str1);
            strcpy (str1,str2);
            strcpy(str2,temp); }//SWAP
void swap(double x, double y){ 
            double temp;
            temp=x;
            x=y;
            y=temp; }//SWAP
int main(){
            char password[30],newpassword[30];
            double x,y;
            cout<<"ENTER YOUR PASSWORD: ";   cin>>password;
            cout<<"ENTER YOUR NEW PASSWORD: ";  cin>>newpassword;
            swap(password,newpassword);
            cout<<"ENTER A VALUE: ";   cin>>x;
            cout<<"ENTER THE NEW VALUE: ";   cin>>y;
            swap(x,y);
            cout<<"YOUR PASSWORD IS: "<<password<<endl;
            cout<<"THE VALUE IS: "<<y<<endl;
            return 0;
}//MAIN 
 

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

               

 

Text Box: ENTER YOUR PASSWORD: windows
ENTER YOUR NEW PASSWORD: linux
ENTER A VALUE: 500
ENTER THE NEW VALUE: 1000
YOUR PASSWORD IS: linux
THE VALUE IS: 1000
Text Box: Figure 15.2a – Program using overloaded swap function
 
 

 

 

 

 

 

 


 

               

 

 

Text Box: Figure 15.2b – Output of 15.2a
 

  

 

 

 


 

DEFAULT PARAMETER

 

In a function, a default value for a parameter can be assigned if the function call does not provide one. Default parameters are listed last in the parameter list. When one parameter is assigned a default value, the following parameters should be set to their default values as well otherwise there will be a problem. In the following main program, the function call to temporary.findgrosspay(1234); only passes one parameter, the id; therefore, the default values will be set for hoursworked and hourlywage. Default parameters can be very useful in constructors to initialize member data.

 

 

Text Box: #include<iostream>
using namespace std;
class employee{
private: int employeeid, hoursworked;
            double hourlywage, grosspay;
public:             void findgrosspay(int id, int hoursworked=35, double hourlywage=25.00){
                        employeeid=id;
                        grosspay=hoursworked * hourlywage;
                        cout<<"GROSSPAY FOR EMPLOYEE #"<<employeeid;
cout<<" is: "<<grosspay<<endl;   }//FINDGROSSPAY
            };//EMPLOYEE
int main(){
            employee temporary;
            temporary.findgrosspay(1234);  
            return 0;
 }//MAIN
Text Box: Figure 15.3a – Program using default parameters
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

           

 

Text Box: GROSSPAY FOR EMPLOYEE #1234 is: 875

  

 


 

               

Text Box: Figure 15.3b – Output of 15.3a

 

 

 


 

OPERATOR OVERLOADING

 

Defining more than one operation for an existing operator is called operator overloading. In C++, there are a variety of operators:  arithmetic operators such as +, -, * , / and %, bit wise operators such as &  |  ^ , <<, and >>, etc.. With the exception of a few operators, most of the C++ operators can be overloaded.  The C++ compiler has already overloaded some of its operators, such as operator + to add an integer as well as a double; and << bit wise left shift operator for the insertion operator (output). In addition, a C++ programmer can overload an existing operator and give it a new meaning.  Operator overloading can extend the C++ language and an overloaded operator can be used to overload other operators. The purpose of overloading operators is to make the program easy to read and to apply an operation naturally. In reality, people do not have a problem understanding conventional operators because they are self-explanatory; therefore, the task is to mimic conventional operators and with this in mind, the new overloaded operator should be consistent with the original purpose of the operator.

 

 

OPERATOR OVERLOADING EXAMPLES

 

For example, the operator plus + that adds integers and floating decimals can be overloaded to concatenate two strings. A benefit of overloading is that it makes programming code natural and readable. In the following example, the + operator is overloaded to concatenate the two strings BUTTER and FLY.

string3 = string1 + string2;

 

Also, without overloading, the concatenation of two strings can be done as follows:

            string3= concatenate (string1, string2);

Note that you have to write the function for concatenate( ); 

Another example of the overload operator is the multiplication of two arrays such as matrix multiplication or finding the intersection of two sets. In the statement A=B * C; where A, B and C are matrixes, the multiplication operator * is overloaded for matrix multiplication and the assignment operator = is overloaded to assign the result of the matrix multiplication.

 

 

OPERATORS THAT CANNOT BE OVERLOADED

 

The following C++ operators cannot be overloaded:

 

?:  Conditional expression operator such as x>y?max=x :max =y;

.    Class (structure) member operators such as employee.name.

.*  Pointer to member operator such as employee.*name.

::   Scope resolution operator such as stack::top;  

sizeof( ) to determine the size of a type such as  sizeof(int);

 

 

OVERLOAD RESOLUTION RULE

 

How does the compiler know which function or operator to use now that several exist? The C++ compiler applies a set of rules such as matching the exact type from the argument list or the type of operands.  A resolution rule may have to apply a conversion rule. It is possible that one function call (overloaded) matches more than one function’s definition; this may cause an ambiguity that may lead to a problem for the compiler that should have been handled properly.

 

Also, when you overload an operator you cannot change the order of the operator’s precedence and you cannot change operator's associativity. In the following example,     a- b* c + d, the order of precedence for multiplication is higher than addition, and subtraction is performed first before addition due to its associatively (left to right).  Note that when two operators have the same precedence, they work according to their associatively: either from left to right or from right to left.

 

 

HOW TO OVERLOAD AN OPERATOR

 

In order to overload an operator you must write a function for that operator so that C++ will call the function to do the process when the operator is used. The overload function definition is the same as ordinary functions except that the keyword operator is used before the parenthesis of the function’s argument list. One thing you must realize when you are making an overloaded operator is that you are calling a function except that you do it with a class object. Ask yourself what kind of parameters the function needs and what the function will return. Obviously the overloaded operator will be used in the same manner as the ordinary operator is used. The following illustrates the general syntax of an overloaded operator prototype with one sample example:

returntype  operator op (parameters);

 

OVERLOADING MATH OPERATORS:  BINARY + OPERATOR

 

The binary operator + is used to add two numbers whether they are integers, floats, doubles, or even characters. In fact the C++ compiler has overloaded all these operations under one operator +. The question is how to add more operations to existing operators. C++ allows overloading by simply writing the function for what the overloaded operator should do. After the function is written, the operator will be used in the same way it has been used normally. For example, an employee may have two sources of income, one from a full time job and one from a part time job. Therefore to compute the total salary we have to compute the full time as well as part time salary. Overloading allows the use of the operator + as it is used in the normal addition of numbers, but here + is applied to a user data type which results in self-explanatory programming code.

            totalsal= fulltimesal + parttimesal; 

Let’s not forget that we have to write the function to take care of the above overloading. Once the function is written, then naturally the operator can be used over and over. If we did not want to use overloading, our statement would look like the following, possibly with several parameters.

            totsalary = findfulltimesal(…..) + findparttimesal(….); 

 

OVERLOADING BINARY + OPERATOR: PROGRAM

 

The following program illustrates overloading the + operator to add two objects of the employee class known as fulltime and parttime. This allows us to calculate the total salary of an employee whose income comes from two different sources.   

 

Hosted by www.Geocities.ws

1