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.
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.


![]()
![]()
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](chapter_15_files/image005.gif)

![]()

![]()
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);
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.
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.

![]()
![]()
![]()
PREFIX AND POSTFIX OPERATOR OVERLOADING
Prefix or postfix operators, ++ (increment operator) and -- (decrement operator), can be overloaded for use with user defined types in a similar way as other operators. Again the idea of overloading is to make the program more understandable and not to make it confusing. You do not want to overload ++ to decrement or overload -- to perform increment. The following simple program illustrates the overloading of the increment operator ++ for a type known as a date. The program keeps track of the working day by adding one to each day with a range of 1 to 5. The same program can be extended to add one to the day of the month.
The general form of an increment overloading is:
classtype &operator++(classtype &obj)

![]()
![]()
![]()
A friend function is not a member of a class but it has access to the class's private and protected members. A friend function is declared in the class that grants the access. To recall every member function implicitly has a pointer to its object known as this pointer. However a friend function does not have a this pointer and for this reason all of the necessary objects need to be passed explicitly to the friend function. For example, using a friend function to overload a binary operator. To declare a function as a friend of a class, you must precede the function prototype in the class definition with the keyword friend.
Every member function has an implied parameter, called this pointer. The value of this points to the class-object (class argument) of the member function. In order to refer to the implicit argument that is passed to the member function, the keyword this preceded by an asterisk is used.
The following three statements perform the same task and show how this pointer is used within a member function. In the first version the keyword this is implied.
print( ){ cout<<findgrosspay(); }
print ( ){cout <<(*this).findgrosspay();
print( ){cout<<this->findgrosspay();
Friend functions and this pointers are further discussed in a later chapter.
OVERLOADING INPUT AND OUTPUT OPERATORS: >> AND <<
In C language the operators >> and << are used as right-shift and left-shift, respectively. However in C++ these operators are overloaded for input (extraction) and output (insertion). You can also overload these operators to work with your own abstract data type (class object). The function that does the overloading operator <<( ) is a friend function since it is not a class member. This function returns a reference to ostream; this is done by placing an & in the function header. The two arguments are a reference to an ostream object and a reference to the object that is to be output.
The general prototypes for >> and << overloading can be shown as follows:
istream& operator >> (istream& parameter1, datatype& parameter2);
ostream& operator <<(ostream& parameter1, datatype& parameter2);
EXAMPLE OF I/O OVERLOADING
How is it possible to input or output a long list of information for an employee class in one instance without going through field by field? One solution is to overload the input or output operators so that when they are used in the program they can input and output all the data. In fact, you can customize the output the way you want to and for beginners I/O overloading is a meaningful example of how overloading can be useful. In the following example the >> extraction and << insertion operators have been overloaded.
![Text Box: #include<iostream >
#include<string.h>
using namespace std;
class employee{
private: char name[20];
int hw;
double hr,taxrate;
double grosspay,taxamount,netpay;
public: void compute(){
taxrate=0.15;
grosspay=hw*hr;
taxamount=grosspay*taxrate;
netpay=grosspay-taxamount; }//COMPUTE
friend istream& operator >>(istream& cin , employee& individual );
friend ostream& operator << (ostream& cout, const employee& individual);
};//EMPLOYEE CLASS
istream& operator >>(istream& cin , employee& individual){
cout<<"ENTER NAME, HOURS WORKED, HOURLY RATE: ";
cin>>individual.name>>individual.hw>>individual.hr;
return cin; }// >>
ostream& operator <<(ostream& cout, const employee& individual){
cout<<"EMPLOYEE NAME: "<<individual.name<<endl;
cout<<"GROSS PAY: $"<<individual.grosspay<<endl;
cout<<"TAX AMOUT: $"<<individual.taxamount<<endl;
cout<<"NET PAY: $"<<individual.netpay<<endl;
return cout; }//<<
int main(){
employee regularemp;
cin>>regularemp;
regularemp.compute();
cout<<regularemp;
return 0;
}//MAIN](chapter_15_files/image020.gif)
![]()

![]()
x=y;
double hoursworked, hourlywage;
. . .
}//EMPLOYEE
employee manager, ebrahimi;
manager=ebrahimi;
The equality operator = = can be overloaded so that it can be applied to class objects, for example comparing the time of two objects known as time1 and time2. Note that after the = = operator is overloaded the following statement could be used:
To overload the = = operator we have to write a function that takes an argument of the class type and compares its data members with the data members of the passed object (right side) and returns a Boolean value (true or false). The following is the function to overload the equality operator for the time class; it compares two time objects to see if they are equal by testing the hours, minutes, and seconds.
bool time::operator= =(const time& appointment){
if ((hour==appointment.hour)&&(minute==appointment.minute) &&
(second==appointment.second)) return true;
else return false; }// END= =
OVERLOADING AN INDEX OPERATOR [ ]
Note that in the following statement that uses overloaded [ ], the string s is used as an index.
freq[s]=freq[s]+1;
Most of the C++ operators can be overloaded, but there are few that cannot be overloaded. Keep in mind, operator overloading should make the program easier and the programmer should be able to use the operator in a natural way and eventually overloading should lead to reusability and less programming code. Improper usage of operator overloading can result in programming chaos. For example, overloading ++ to perform subtraction instead of addition would lead to confusion. Depending on what you want to do, you may want to overload an operator. Among the more frequently used overloaded operators we can name +, >>, <<, =, = =, and ++. Notice that while you can add additional meaning to the existing operators, you cannot create a new operator even though it is highly desirable such as exponentiation (**). Moreover, you cannot change the required number of operands; for example, a unary operator cannot have more than one operand.
A constructor is a member class that initializes an object and is called automatically as the object is created. Remember, a constructor has the same name as its class and does not return a value. Moreover, a constructor that has no parameters is known as a default constructor.
A constructor can be overloaded with different data types. For example, a stack class can have more than one constructor to initialize the stack with character type numbers or to initialize the stack with integer type numbers.


Abstraction is the process of focusing on the essential and relevant aspects of an object or a task (function) without getting bogged down in their unnecessary details (molecular structure). Abstraction means to generalize an object and hide its details. To apply abstraction to objects, one must classify the objects according to their similarities as to what they do and what they have. One method of abstraction is to classify objects according to the domain of the problem as to the requirements at the moment, the characteristics of the objects, and how these objects interact with each other. An abstraction can have many layers of abstraction itself. Abstraction is around us daily, we express and represent ideas in abstract terms. We should not confuse abstraction with impossibilities (e.g. painting); however, some abstractions are difficult to figure out depending on the situation. You can think of abstraction as a box, and within the box is another box, and so on. How would you use abstraction to classify the following objects?
Lion, tiger, cat, mouse, horse, rooster, bat, fish, frog, lobster, snake. Can you categorize the objects around you in any of the four elements of air, earth, fire, and water?
The world around us is composed of objects like book, mouse, and window. Each object comes from a class or blueprint (pattern). Classes correspond to categories (classifications) and are general terms while objects correspond to individuals (instances) and what you are dealing with at the moment. You can say a class is a blueprint and an object is an instance of the class. Think of a house blueprint and your own house. The kind of house is the class and your particular house is an object. Every object is an instance of a class. For example, date is a class and my birthday is an instance of class date.
INFORMATION HIDING (DATA HIDING)
Information hiding is applying an access restriction on data that the user should not be exposed to. Data hiding helps prevent errors that result from intentional or inadvertent changes in data. Keep in mind that by applying abstraction we are hiding and encapsulating data and vise versa. Think of your computer as an object of a computer class where internal components (details) are hidden in a box and communication is done through an interface (keyboard, mouse, or screen).
A group of several related functions with the data they manipulate is known as a module. In a modular programming, a program (large program) is divided into several modules where in each module its data is hidden. Each module is placed into separate namespaces or files, which can also be compiled separately.
How the module works (user interface) is kept separate from how the module is implemented. Separating the user interface from the implementation enables a user to change the implementation without changing the interface.
HOW TO MAKE AN INCLUDE FILE
By this time you are fully aware that every C++ program requires an include file ranging from I/O to math and standard libraries. In fact one reason the C/C++ language is a compact, and as result, fast language is that you only include what you need in a program. Even cin and cout are not part of the C++ language itself, you have to include the library for them. For example, if you need to do a variety of mathematical functions, you place #include <math.h> in your program. The C++ compiler keeps the program and data for these libraries in separate files (modules) and when needed you can add them to the head (top) of your program. Do you know why these files are called header files? Using these modules contributes to information hiding and a programmer can make their own header files and include them in a program when needed. Commonly the class and function prototypes are kept in a header file. To make a header file, just as making any ordinary file, type the information and save it under a filename with extension .h (for example employee.h). To use your own include file, instead of angle brackets, surround the file name in double quotations as shown below.
#include “employee.h”
Encapsulation is a way to put together (to enclose in a capsule) data (attributes) and the functions (behavior) that manipulate the data into one self-contained unit (package) and safeguard it from outside misuse. In object-oriented programming the encapsulation concept is achieved by means of a class where data and functions can be either private or public to the object. The private data members and member functions are hidden from the class user; they are encapsulated within the class and they are not accessible from outside of the class. However, through the public parts (as an interface) of a class, the private elements can be accessed.
In C++, abstract data types (ADT) are implemented by having a class where the member variables are declared as private and some of the member functions are public. These public member functions are used as an interface to access the private members. Putting an access restriction on the data in a class will maintain data integrity and consistency. The definition of class can be placed in a separate file and then be compiled; and whenever it is needed it can be included in different programs. Similarly the class implementation can be placed in a different file that can be included with other programs that need them.
TEMPLATE
How would you write a program that searches for a number like salary or for an employee’s name? How would you write a stack program where you can push either a number or a string? You may respond quickly that you would write a separate program for each data type. By using template, a C++ programmer can design generic algorithms and generic classes. With a template your algorithm can work for integers as well as floating-point numbers. In C++, you specify what type of data to work with by the function call or when an object is declared (instantiated). One advantage of the template is that it promotes program reusability and in the long run programming becomes easier.
TEMPLATE FUNCTION
A template function is a function that works with a generic data type such as writing one function that works with any type of data, whether it is a built-in or user-defined type. In a template function the actual data type is not specified; rather, the generic data type is used. On a function call with the arguments (actual data types), the compiler will substitute the parameters for the actual data type such as: integer, character, or other data type. The actual value type parameter can also be used for local variables as well as the return value of the function. A template function includes a template definition followed by a function definition. The function template starts with the keyword template following by an angle bracket enclosing the keyword class with a parameterized data type (generic type) name.
After the template definition the function definition would be the same except the generic type name would be used for the parameterized data type. The general syntax of a template function is shown below:
template < class generictypename>
generictypename functionname (generictypename parametername){
functionbody;
return functionvalue; }
TEMPLATE FUNCTION: PROGRAM
The following program finds the smaller of two values whether they are integers, characters, or floating decimal numbers. The template function will take care of the different data types. The generic data type in the template function will be substituted with the actual data type provided by the calling function. Note that GT is an identifier name and as a convention I used capital letters to represent it. Other conventions have used identifier names such as T and Type.


![]()
![]()
TEMPLATE WITH MULTIPLE TYPES
It is possible for a template to have more than one type. For instance, in computing gross pay, the hours worked is an integer, however the hourly rate and gross pay are doubles. The general syntax of a template function having multiple types is as follows:
template <class T1, class T2>
T2 computegrosspay (T1 hoursworked, T2 hourlyrate){
T2 grosspay;
grosspay=hoursworked * hourlyrate; return grosspay; }//GROSS
T2 computetotalprice (T1 quantity, T2 unitprice){
T2 totalprice;
totalprice=quantity * unitprice; }//TOTALPRICE
In the above two examples, T1 and T2 are the type identifiers that will be replaced by the two different actual data types.
OVERLOADED FUNCTIONS VERSUS TEMPLATE FUNCTIONS
Function overloading becomes useful when performing similar operations on different data types. In function overloading we use only one function name with several different versions of the function even though the whole operation is identical. However when using template functions, we have one function name with one version of the function that is parameterized and the compiler generates different versions of the function based on the data type provided by the function call. For example we could have a function called sort to be overloaded so it will cover a variety of sorting algorithms (generic algorithms) with many different swaps. One disadvantage of function overloading is that if one function needs to be changed, all the functions must be changed. It should be noted that a template function could be overloaded in the same way as a regular function.
CLASS TEMPLATE
A class template is a class that can have a generic data type instead of an actual data type. The actual data type for a class will be provided as the class is instantiated and the compiler will generate the proper code by substituting the generic type with the actual type.
The general syntax for a class template is the same as a function template, which starts with the keyword template followed by the keyword class and its parameterized type enclosed in angle brackets.
The class definition is done in the same way as an ordinary class, except that the generic type (parameterized type) is used in place of an actual type. Remember to place the actual data type in angle brackets when the object is instantiated. One good usage of class templates is to build a generic stack, queue, or tree. You can define a generic stack with an unspecified data type. Remember that every time you use a template class or its member functions, the template definition must precede the class definition or function definition. For clarity you may want to place the template definition on a separate line.

![]()

![]()
CLASS TEMPLATE: GENERAL SYNTAX
When you are using a class template, make sure to distinguish between the general syntax for the class itself, its members, and when the object is instantiated. The following example demonstrates each of the above cases:
template <class typeidentifier>
class classname{
……
typeidentifier …variablename.
typeidentifier functionname (typeidentifier....);
}; //CLASS
template <class typeidentifier>
typeidentifier classname <typeidentifier>:: functionname (typeidentifier…){
…..
return ….; }//FUNCTION
main(){
…..
classname <actualtype> objectname
….. }//MAIN
STACK WITH TEMPLATE: GENERIC CLASS PROGRAM
A stack is a data structure and an ADT where items are added and removed from one end. The function push( ) inserts a new item to the stack and pop( ) removes the item that was most recently inserted. To summarize the stack ADT, items are removed according to the last-in-first-out discipline. The functions isempty( ) and isfull( ) check the stack to determine whether it is empty or full, respectively. The following program defines a generic class called stack with a maximum of 5 items, including double and character values. The operand stack is used to hold the numbers while the operator stack holds the character operators. The stack can be extended to hold other different data types as well.
![Text Box: #include <iostream>
using namespace std;
const int MAXSIZE=5;
template <class T>
class stack{
public: stack(void);
bool isempty() const;
bool isfull() const;
void push(T x);
T pop();
private: int top;
T items[MAXSIZE]; }; //STACK
template<class T>
stack< T > :: stack(){ top = -1;}
template<class T>
bool stack <T> :: isempty() const{ return(top == -1); }//ISEMPTY
template<class T>
bool stack <T> :: isfull() const{ return(top == (MAXSIZE-1)); }//ISFULL
template<class T>
void stack<T> :: push (T x){
if (isfull()) cout<<"YOU CAN'T PUSH"<<endl;
else { top++; items [top] = x; } }//PUSH
template<class T>
T stack <T>:: pop(){
if (isempty()){cout<<"YOU CAN'T POP"<<endl; return 0; }//IF
else return items [top--]; }//POP
int main( ){
stack<double> operandstack;
operandstack.push(3.00); operandstack.push(12.5); operandstack.push(1.2);
cout<<"STACK VALUE IS:"<< operandstack.pop()<<endl;
operandstack.push(8.00); operandstack.push(2.00); operandstack.push(5.4);
while (! operandstack.isempty()) cout<<"STACK VALUE IS:"<< operandstack.pop()<<endl;
stack <char> operatorstack;
operatorstack.push('+'); operatorstack.push('*');
operatorstack.push('-');operatorstack.push('/');
while (! operatorstack.isempty()) cout<<"STACK VALUE IS:"<< operatorstack.pop()<<" "<<endl;
return 0;
}//MAIN](chapter_15_files/image035.gif)
![]()
![]()
QUEUE WITH TEMPLATE
A queue is a data structure or an abstract data type (ADT) where insertion is done on one end and removal is done on the other end. The following example implements a queue with a template, enabling the queue to work with a variety of data types. The following template queue is tested with int and char types, however one can extend the template queue to work with other data types and include overloading, making it more powerful and complex.
#include <iostream>
using namespace std;
const int MAXSIZE = 10;
template <class T>
class queue {
private: int front, rear,size;
T info[MAXSIZE];
public: queue(int);
void enqueue(T x);
T dequeue( );
bool isempty( ) const;
bool isfull() const; };//CLASS QUEUE
template<class T>
queue <T>:: queue(int s=MAXSIZE){
front = 0;
rear = 0;
size=s+1; }//CONSTRUCTOR
template<class T>
bool queue <T>:: isempty() const{ return (rear == front); }
template<class T>
bool queue <T>:: isfull() const { return ((rear + 1) % size == front); }//ISFULL
template<class T>
void queue <T>::enqueue(T x){
if(isfull()) cout<<"QUEUE FULL:"<<endl;
else{ rear = (rear +1) % size;
info[rear] = x; } }//ENQUEUE
template<class T>
T queue <T>::dequeue( ){
if( isempty() ){cout<<"QUEUE EMPTY"<<endl;
return -1;}//IF
else{ front = (front + 1) % size;
return info[front];}//ELSE
}//ENQUEUE
int main(){
queue <int> myintqueue(5);
for (int i=0; i<=5; i++){
myintqueue.enqueue(i); }//FOR
while(!myintqueue.isempty()){ cout<<myintqueue.dequeue()<<" "<<endl;}//WHILE
queue <char> mycharqueue(4);
for (char c='A'; c<='E'; c++){
myintqueue.enqueue(c); }//FOR
while(!myintqueue.isempty()){ cout<<char(myintqueue.dequeue())<<" "<<endl;}//WHILE
return 0;
}//MAIN

![]()
`
![]()
TOPICS NOT COVERED HERE
The topic of overloading, especially operator overloading, can become tedious and error prone. When an operator is overloaded, there are many versions of its function and, on top of the ambiguity as to which function to pick, conversion of one type to another must take place. Type conversion by itself needs lengthy coverage as well as how to deal with passing an object as a parameter or returning an object from a function, e.g. passing a large object versus small one. Controversial issues surrounding the friend function are not discussed here. Virtual functions need their own attention as to how C++ chooses the correct overridden functions during run-time, creating run-time polymorphism. Virtual functions become a very interesting subject when they work with a pointer to the base class and then each derived class calls its own function although the function name remains the same. The advantage of templates is that the programmer can design generic algorithms and classes. However, templates have time and space overhead, which may not be ideal for real-time applications. The use of templates can become more complicated by introducing nested templates with multiple parameters. The topic of polymorphism with virtual functions requires knowledge of inheritance and will be discussed in the next chapter.
Whether you want to apply brakes on a bike, car, van, or truck, they all have one task in common; the result is the vehicle coming to a stop. Also, the process of finding the area of a geometric shape is similar whether the area is of a rectangle, triangle, or circle. The same is true for printing, regardless of whether you are printing a list, queue, or stack. One benefit of overloading is the ability to give one meaningful name to several functions that have the same task, rather than giving a different name to each function. For example, in a payroll system many functions with the same name, such as payment( ), can be used for hourly paid or salaried employees as well as for consultants and managers. Another example, double-clicking on an icon may provide different results depending on whether the icon is a word processor, e-mail application, or an executable file.
Polymorphism allows an entity (for example a variable, function, or object) to take on a variety of representations. Function overloading allows us to reuse the same name for functions (or methods) as long as the parameter list differs.
Many operations on newly defined user data types share a common ground with the operations on existing basic data types. Therefore, it is desirable that new user data types use the same operator in the same manner. The process of enabling C++ operators to work with objects is called overloading. In operator overloading, a function is written for the operator so that it can be used normally with the class object. One example is to define a complex number data type and use the same operators such as +, -, *, and / to perform the operations on complex numbers as they would perform on a real number. Another example of overloading operator is to apply it to the object of class date, time, and polynomial. With the use of a template, a C++ programmer is able to write functions and classes regardless of their specific data types.
The next chapter will cover the last aspect of object-oriented programming known as inheritance: when one object carries the properties of one or more other objects. Inheritance is one of the key concepts of object-oriented programming where member variables in one class automatically become part of objects belonging to another class. One class is considered the base class, and the class that inherits from the base class is considered the derived class.
Inheritance, in addition to encapsulation (class) and polymorphism, is a key element of object-oriented programming and enhances programming by reusing and sharing code; in the long run, inheritance is cost effective and minimizes programming errors.
SELF-TEST TRUE / FALSE CHAPTER 15: POLYMORPHISM
__1. Polymorphism is the ability to have many forms for the same name.
__2. An example of polymorphism is when different functions that do a similar task have different names.
__3. Polymorphism, encapsulation and inheritance are important features of object-oriented programming.
__4. Operator overloading is an example of polymorphism.
__5. When a function is overloaded, the same function name is used to perform different tasks.
__6. The compiler uses the function signature to determine which function to call.
__7. A default value for a parameter will be assigned if its value is specified in the function call.
__8. An overloaded operator should be used so that is consistent with the original purpose of the operator.
__9. The + operator is overloaded since it is used to add integers, floats and doubles.
__10. A friend function does not have access to the private and protected members of a class.
__11. By overloading the insertion operator you can output all the information of a class in one statement.
__12. To assign one object to another the assignment operator is overloaded to assign all data in the class.
__13. There is no need to overload the equality operator when testing the equality of two objects of a class.
__14. The index operator can be overloaded to take a class object as the index.
__15. A constructor can be overloaded to initialize members of a class with different data types.
__16. Abstraction means generalizing an object and hiding its detail.
__17. ADT (Abstract Data Type) emphasizes the work that is to be done rather than how it is done.
__18. Objects refer to general categories while classes refer to specific instances.
__19. Information hiding is a means of applying abstraction.
__20. In modular programming, the user interface is kept separate from the implementation.
__21. The following is an example of how you would include your own header file: #include<person.h>.
__22. A class is a means of encapsulation since data and functions are contained in one unit.
__23. Templates are used to design specific algorithms and classes and they work for only one data type.
__24. A template function uses a generic data type that is substituted with the actual data type.
__25. Using a class template, you can define a generic stack for multiple data types.
CHAPTER 15 POLYMORPHISM ASSIGNMENTS
Q15a) What is the main idea behind polymorphism in object-oriented programming? An example of polymorphism is when two functions have the same name but different implementations. For example, the function printlist( ) can be used to print the contents of an array or a linked list.
Q15b) Write an overloaded function for sorting that uses an overloaded swap function.
Q15c) Explain one advantage of default parameters. What is the restriction on default parameters?
Q15d) How does a compiler resolve overloading?
Q15e) What is the idea behind operator overloading? Give an example.
Q15f) Write an overloaded binary operator + for the intersection of two sets and an overloaded – operator for the difference of two sets. Use arrays to represent each set. Display the result using cout<<A+B; and cout<<A-B;
Q15g) What is a friend function? What is an advantage and a disadvantage of having friend functions?
Q15h) How are templates different from function overloading? Give an example of a template using sort with a swap function.
Q15i) What does the following template class do?
#include <iostream >
using namespace std;
const int MAXSIZE=5;
template <class T>
class stack{
public: stack(void);
bool isempty() const;
bool isfull() const;
void push(T x);
T pop();
private: int top;
T items[MAXSIZE]; }; //STACK
template<class T>
stack< T > :: stack(){ top = -1;}
template<class T>
bool stack <T> :: isempty() const{ return(top == -1); }//ISEMPTY
template<class T>
bool stack <T> :: isfull() const{ return(top == (MAXSIZE-1)); }//ISFULL
template<class T>
void stack<T> :: push (T x){
if (isfull()) cout<<"YOU CAN'T PUSH"<<endl;
else { top++; items [top] = x; } }//PUSH
template<class T>
T stack <T>:: pop(){
if (isempty()){cout<<"YOU CAN'T POP"<<endl; return 0; }//IF
else return items [top--]; }//POP
void main( ){
stack<double> operandstack;
operandstack.push(3.00); operandstack.push(12.5); operandstack.push(1.2);
cout<<"STACK VALUE IS:"<< operandstack.pop()<<endl;
operandstack.push(8.00); operandstack.push(2.00); operandstack.push(5.4);
while (! operandstack.isempty()) cout<<"STACK VALUE IS:"<< operandstack.pop()<<endl;
stack <char> operatorstack;
operatorstack.push('+'); operatorstack.push('*');
operatorstack.push('-');operatorstack.push('/');
while (! operatorstack.isempty())
cout<<"STACK VALUE IS:"<< operatorstack.pop()<<" "<<endl;
}//MAIN
Name one advantage of template function as well as template class.
Q15j) What is abstraction? Where does the word come from? What are the similarities between an art abstraction and a programming abstraction?
Q15k) What is the idea behind the ADT? How does ADT hide detail? How has abstraction evolved in programming?
Q15l)
Write an abstract data type known as date with its own attributes and its own
function members. Write a simple program to involve the operations and data.
Q15m) Write an abstract data type known as time with its own data members and member functions. Write a simple program to support the operations defined for the type time.
Q15n) Create an individual universal abstract data type. Start from date of birth, infant, child, teenager, adult, senior, and finally date of rest.
Q15o) Create an abstract data type for employee. Include salary, commission, bonus, and calculate overtime pay. Set the data members and member functions. Test your ADT with a simple program.
CASE STUDY –PAYROLL SYSTEM PHASE 15: POLYMORPHISM
a) Write an overloaded search function for your employee class. This will allow you to use the same function name to search for an employee by either a last name or id number. You will need to write two implementations for the search function, one takes a string as a parameter and the other takes an integer.
b) Overload the insertion operator << to display all the employee information.