Chapter 7
Chapter 7
LECTURE 7
Objective
MULTIMEDIA UNIVERSITY 1
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
1. Introduction to Overloading
In chapter 4, we have seen that we can have more than one constructor per class - this is
an example of overloading. It is also possible to overload other functions and even to
overload operators.
Note that some people refer to overloading as a kind of polymorphism (literally: many
forms from the word polymorphism, Poly means many, and morph means form.),
because polymorphism allows the same operation to be carried out differently, depending
on the operands involved. C++ allows you to overload operators as well. This can be
very handy, as for instance if you want to add one object to another. Ex:
Numbers a,b,c;
a = b + c
Almost all the C++ operators(+,-,=, etc) can be overloaded, but each has its own special
requirements, which are discussed in this chapter.
Overloaded functions and operators can be referred to as compile-time polymorphism or
compile-time binding.
2. Function Overloading
C++ allows the programmer to overload functions, meaning that it is possible to have
several functions with the same name but with different parameter declarations. This
means that overloaded functions can have different implementations but with the same
interface(same name).
Example if there are multiple definitions of a function f, f is said to be overloaded.
Function Overloading Rule:
o The same function name will be used with different number of parameters
and parameters of different type. But overloading of functions with different
return types are not allowed. Functions with the same name and parameter
list, but different return types, generate a compiler error.
Example below of function prototype is NOT adequate for overloading
int f(int)
float f(int)
Below is adequate for overloading. Note that the last 2 prototypes have distinct
signatures because the order or arguments differ
int f(int)
float f()
MULTIMEDIA UNIVERSITY 2
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
Example:
#include<iostream>
using namespace std;
void AddAndDisplay(int,int);
void AddAndDisplay(double,double);
void AddAndDisplay(float,float);
void main()
{ double m,n;
m=11.05;
n=14.055;
float x,y;
x=m;
y=4.5;
AddAndDisplay(10,10); //will call function with prototype
//AddAndDisplay(int,int);
MULTIMEDIA UNIVERSITY 3
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
Output:
Integer result: 20
Double result: 25.105
float result: 15.55
Press any key to continue
Some times when these overloaded functions are called, they might cause ambiguity
errors. This is because the compiler may not be able to decide what signature function
should be called.
If the data is type cast properly, then these errors will be resolved easily. Typically,
function overloading is used wherever a different type of data is to be dealt with. For
example this can be used for a function which converts farenheit to celsius and vice
versa. One of the functions can deal with the integer data, other can deal with float for
precision etc.,
To overload a method, create more than one method with the same name, but with a
different signature. For method overriding to be possible, a method in a derived class with
the same name as a method in the base class must be created and both methods (in
derived and base) must have the same signature.
A child class inherits access to any public member function of a parent class. For any
given parent function, the child class can choose to either:
MULTIMEDIA UNIVERSITY 4
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
o use it: The child can use it, just as if it were its own function.
o overload it: The child can overload it by specifying a different argument list and
providing an implementation.
o override it: The child can override the parent function by keeping the same
name and argument list, but supplying a new implementation.
#include<iostream>
using namespace std;
class Base {
protected: int bdm;
public:
Base( ): bdm (0) { }
Base(int i): bdm (i) { }
~Base( ) { }
void Display( ) {
cout<<"Base::bdm:"<<bdm<<endl;}
};
};
void main( ) {
Base b_obj;
Derived d_obj;
b_obj.Display( );
d_obj.Display( );
}
Output:
Base::bdm:0
Base::bdm:0
Press any key to continue
MULTIMEDIA UNIVERSITY 5
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
#include<iostream>
class Base {
public:
~Base( ) { }
void Display( )
{ cout<<"Base::bdm:"<<bdm<<endl<<endl; }
};
Function Display() is
class Derived : public Base { overloaded in this program
protected: int ddm;
as there are 2 distinct
signatures of this function (1
public: each in base and derived
class)
Derived( ):Base( ){ ddm=0;}
~Derived( ) { }
void Display(int d)
{ ddm=d;
cout<<"Base::bdm:"<<bdm<<endl;
cout<<"Derived::ddm:"<<ddm<<endl<<endl;
};
void main( ) {
Output:
Base b_obj;
Base::bdm:0
Derived d_obj;
Base::bdm:0
b_obj.Display( );
Derived::ddm:77
d_obj.Display(77);
Press any key to continue
}
MULTIMEDIA UNIVERSITY 6
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
Overriding, also called polymorphism, means that a base class object and a child class
object can both call the same function, in the same manner.
In all the examples in this chapter, we’re using compile-time polymorphism which
means the compiler determines which function( in the classes having the same form)to
execute whenever a function is invoked during compilation.[note: run-time polymorphism
which uses virtual functions will be studied in later chapters]
For objects of a derived class the compiler will choose the member function of the
derived class if the same function name exists in both base and derived classes. See
example below.
For objects of a base class, the compiler has no other option than to choose the
member defined in the base class, since the base class knows nothing of the derived
class. See example below.
This is a convenient and frequently used property of derived classes, because it allows
the same function name to be used for objects of base and derived classes.
But, we can call base class overridden member function using the scope resolution
operator (::)
MULTIMEDIA UNIVERSITY 7
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
class Base {
protected: int bdm;
public:
Base( ): bdm (0) { }
Base(int i): bdm (i) { }
~Base( ) { }
void Display( )
{
cout<<"Base::bdm:"<<bdm<<endl<<endl;
}
};
};
Output:
void main( ) {
Base b_obj;
Base::bdm:0
Derived d_obj(4);
Base::bdm:4
b_obj.Display();
Derived::ddm:4
d_obj.Display();
Press any key to continue
}
MULTIMEDIA UNIVERSITY 8
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
Example 4: Call base class overridden member function using the scope resolution
operator (::)
#include<iostream>
using namespace std;
class Base {
protected: int bdm;
public:
Base( ): bdm (0) { }
Base(int i): bdm (i) { }
~Base( ) { }
void Display( )
{
cout<<"Base::bdm:"<<bdm<<endl<<endl;
}
}; Using scope
resolution operator to
access the overridden
class Derived : public Base {
member function.
protected: int ddm;
public:
Derived( ):Base( ){ ddm=0;}
Derived(int i):Base(i), ddm (i) { }
~Derived( ) { }
void Display()
{ Base::display():
cout<<"Base::bdm:"<<bdm<<endl;
cout<<"Derived::ddm:"<<ddm<<endl<<endl;
}
};
d_obj.Display(); Base::bdm:4
} Derived::ddm:4
MULTIMEDIA UNIVERSITY 9
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
2. Operator Overloading
We all know that an operator can be used in mathematical expressions:
int z,x,y;
x=4;
y=10;
z=x+y;
float g=10;
g=3.14*g;
Now wouldn't it be nice to use operators on our own objects to do what we want? For
example, a string class could use + to concatenate, or a Date class could use the
< and > operators to compare dates objects.
Using operator overloading, operators can be programmed to do whatever it is
programmed to do. The purpose is to make programs clearer by using conventional
meanings for ==, [], +, etc.
• Operator overloading offers a programmer a more elegant and powerful mathematical
shorthand for performing operations on object.
In C++, Operator overloading refer to multiple definitions of operators such as
+ ++ % =
- -- == &&
new [] ! <
> >= <= !=
Operator overloading is also simply another way for you to make a function call. To
overload an operator, a programmer needs to write a method that will redefine the
operator to perform a certain action each time it is applied to a certain objects. Methods
that can be redefined using operator overloading includes friends functions, non-
member and member functions of a class.
MULTIMEDIA UNIVERSITY 10
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
Example 1: Class MyString that contains a function that concatenate string of the objects
#include<iostream>
#include<string>
using namespace std;
class MyString
{ private: char word1[100];
public:
MyString(char s[])
{
strcpy(word1, s);
}
MyString()
{
strcpy(word1,"Hello");
}
char* getString()
{
return word1;
}
};
void main( ) {
MyString s1;
MyString s2("Kitty");
s1=s1.add(s2);
cout<<s1.getString()<<endl;
MULTIMEDIA UNIVERSITY 11
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
#include<iostream>
#include<string>
using namespace std;
class MyString
{
private: char word1[100];
public:
MyString(char s[])
{
strcpy(word1, s);
}
MyString()
{
strcpy(word1,"Hello");
}
char* getString()
{
return word1;
}
};
MULTIMEDIA UNIVERSITY 12
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
You can see from the 2nd example that s1+s2 is similar to s1.add(s2). Both statements are
calling functions to a function in the class that takes an argument which is s2 object and
concatenates the word1of s2 (s2.word1) object and with the word1 in s1 object (just word1,
because it is s1 that makes the call to the function).
s1+s2 makes a call to operator +(…). We can also invoke operator +(…) by the calling
function s1.operator+(s2) in main().
Therefore s1+s2 is synonymous with s1.operator+(s2) in that they both call the function that
has the following signature :
MyString& operator +(MyString val)
We can see from this 2 examples that operator+(in the 2nd example) is another name that
has been redefine for the original function add(in the 1st example).
Here is the syntax for overloaded operators, where op is the operator being overloaded:
In implementing operator overloading, ensure that the operator used does not stray far
from its ordinary sense. For instance, don’t use + if you want to provide an operator that
outputs members of a class; use << instead. If + is used in this case, it would be rather
confusing and misleading to be used in a program.
MULTIMEDIA UNIVERSITY 13
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
When, an operator is overloaded, its basic properties must be preserved. For instance,
any overloaded operator retains its original precedence and associativity. It also retains
its arity (number of operands). Of course, some operands, such as + and – have more
than one arity, so they can be overloaded either way. Preservation on the positioning of
the operator is also important. For instance, the ! operator must always be placed in front
of its operand.
You cannot invent a new symbol and overload it. For instance, C++ does not have a $
operator, so this symbol cannot be overloaded.
Finally, you cannot overload operators for use with primitive (built-in) operands; one or
more operand must be a class type. It is not possible to overload operators involving only
built-in data types. For example, an attempt to overload addition, +, for the int data type
would result in a compiler error. int operator+(int i, int j) is not allowed.
MULTIMEDIA UNIVERSITY 14
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
x=n1;
y=n2;
}
void Add ( const Point &p1, const Point &p2)
{
x = p1.x + p2.x;
y = p1.y + p2.y;
}
void Subtract ( const Point &p1, const Point &p2)
{
x = p1.x - p2.x;
y = p1.y - p2.y;
}
void Multiply( const Point &p1, const Point &p2)
{
x = p1.x * p2.x;
y = p1.y * p2.y;
}
void display()
{
cout<<"x : "<<x<<endl;
cout<<"y : "<<y<<endl<<endl;
}
};
void main( ){
Point p1 (3.0, 4.0);
Point p2 (1.0, 2.0);
Point p3, p4, p5; Output:
p3's values
p3.Add(p1, p2); x : 4
p4.Subtract(p1, p2); y : 6
p5.Multiply(p1, p2); p4's values
cout<<"p3's values"<<endl; x : 2
y : 2
p3.display();
cout<<"p4's values"<<endl; p5's values
x : 3
p4.display(); y : 8
cout<<"p5's values"<<endl;
Press any key to continue
p5.display();
}
MULTIMEDIA UNIVERSITY 15
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
#include<iostream.h>
class Point{
private: double x, y;
public:
Point()
{
x=y=0.0;
}
void display()
{
cout<<"x : "<<x<<endl;
cout<<"y : "<<y<<endl<<endl;
}
MULTIMEDIA UNIVERSITY 16
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
};
void main( ){
Point p1 (3.0, 4.0);
Point p2 (1.0, 2.0);
Point p3, p4, p5;
Output:
p3=p1 + p2; //same as p1.operator+(p2);
p3's values
p4=p1 - p2; //same as p1.operator-(p2);
x : 4
p5=p1 * p2; //same as p1.operator*(p2); y : 6
cout<<"p3's values"<<endl;
p4's values
p3.display(); x : 2
y : 2
cout<<"p4's values"<<endl;
p4.display(); p5's values
cout<<"p5's values"<<endl; x : 3
y : 8
p5.display();
Press any key to continue
Based on the example, the +, - and * operator takes a different meaning as they are
overloaded. This means that whenever we see a statement having the general form:
Object1 + Object2;
The member function with the name operator<overloaded operator> will be called on Object1
and Object2 will be passed as an argument to the member function that is using operator
overloading.
This means that operator+ (…) will be called on object p1, and object p2 is passed by
reference(since the argument in the operator overloaded function takes a reference object).
MULTIMEDIA UNIVERSITY 17
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
o adds the x of the object that called the function with the p2.x of object, and also
does the same for the y and returns a new object having the result of the addition
to p3.
2.3 Overloading the Unary Increment (++) and Decrement (--) Operator
• Overloading the prefix (++p) operator increments each data member by the value of 1
and then returns the incremented object.
• Overloading the postfix (p++) increment operator C++ adopts a similar style to the
prefix operator, but uses a dummy member function argument of type int.
• A similar procedure is exercised for the prefix and postfix decrement operators.
passes p1 by reference to function operator ++(), and the function increments the x and
y of object p1 first. Then, the function returns the object(that has been incremented) to
the main.
passes p2 by reference to function operator ++(int), and the function returns the object
first (before incrementing the x, and y) to the main.
#include<iostream.h>
class Point{
private: int x, y;
public: Point();
Point(int, int);
Point operator ++ ( );
Point operator ++(int);
Point operator -- ( );
Point operator --(int);
void display();
};
Point::Point()
{
MULTIMEDIA UNIVERSITY 18
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
x=y=0;
}
Point Point::operator ++ ( )
{
++x;
++y;
return Point(x, y);
}
Point Point::operator -- ( )
{
--x;
--y;
return Point(x, y);
}
x : 3
y : 4
MULTIMEDIA UNIVERSITY 19
Press any key to continue
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
void main( )
{ Point p1 (2, 3);
Point p2 (2, 3);
Point r;
r =p2++;
cout<<"r=p2++ ="<<endl;
r.display();
p2.display();
cout<<endl;
}
Example:
#include<iostream.h>
class Point{
private: double x, y;
public:
Point();
Point(double, double);
void display();
Point operator = (const Point &p);
};
Point::Point()
{
x=y=0;
}
MULTIMEDIA UNIVERSITY 20
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
void Point::display()
{
cout<<"x : "<<x<<endl;
cout<<"y : "<<y<<endl<<endl;
}
void main( ){
Output:
Point p1(3.0, 4.0);
Point p2(1.0, 2.0); p1 object
cout<<"p1 object "<<endl; x : 3
y : 4
p1.display();
cout<<"p2 object "<<endl; p2 object
x : 1
p2.display(); y : 2
In the example above,the invoking object is p2. p2 will call the function operator=(..)
passing p1 by reference.
MULTIMEDIA UNIVERSITY 21
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
Point::Point()
{
x=y=0;
}
Point::Point(double n1, double n2)
{
x=n1;
y=n2;
}
void Point::display()
{
cout<<"x : "<<x<<endl;
cout<<"y : "<<y<<endl<<endl;
}
double Point::getX()
{
return x;
}
double Point::getY()
{
return y;
}
MULTIMEDIA UNIVERSITY 22
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
void main( ){
Point p1(3.0, 4.0);
Point p2(1.0, 2.0); Output:
Point p3, p4;
x : 4
y : 6
p3 = p1 + p2;
p4 = p1 - p2; x : 2
y : 2
Point operator + (Point p1, Point p2) // p1, p2(fr main) is passed by
// value to the parameters p1,p2
The operator overloaded function here returns an object to the calling function and this
object will be assigned to p3.
If we want to use non-operator overloaded function, the calling function could be written
as
add(p1, p2)
and the function called can have the form below:
Point add (Point p1, Point p2) { //statements }
Notice that there is NO object that invokes the operator+ function. As the function that is
using operator overloading is a non-member of the class.
MULTIMEDIA UNIVERSITY 23
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
#include<iostream.h>
class Point{
private: double x, y;
public:
Point();
Point(double, double);
friend Point operator + (Point, Point );
friend Point operator - (Point, Point );
void display();
};
Point::Point()
{
x=y=0;
}
Point::Point(double n1, double n2)
{
x=n1;
y=n2;
}
void Point::display()
{
cout<<"x : "<<x<<endl;
cout<<"y : "<<y<<endl<<endl;
}
void main( ){
Point p1(3.0, 4.0);
Point p2(1.0, 2.0);
MULTIMEDIA UNIVERSITY 24
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
p3 = p1 + p2;
p4 = p1 - p2;
p3.display();
p4.display();
}
Example:
#include<iostream>
using namespace std;
class Date
{
private:
int day;
int month;
int year;
public:
Date()
{
day=month=year=0;
}
Date(int d, int m, int y):day(d), month(m),year(y)
{ }
MULTIMEDIA UNIVERSITY 25
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
};
void main()
{
Date date1(10,10, 2003);
cout<<date1.get_month()<<"/"<<date1.get_day()<<"/"<<date1.get_year();
}
class Date
{
private:
int day;
int month;
int year;
public:
Date()
{
day=month=year=0;
}
Date(int d, int m, int y):day(d), month(m),year(y)
{ }
MULTIMEDIA UNIVERSITY 26
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
};
This means that the calling function cout<<d can also be rewritten as
operator<<(cout,d); in the main()
The overloaded operator function can also be written as a friend function as below:
MULTIMEDIA UNIVERSITY 27
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
#include<iostream>
using namespace std;
class Date
{
private:
int day;
int month;
int year;
public:
friend ostream &operator << (ostream&, const Date&);
Date()
{
day=month=year=0;
}
Date(int d, int m, int y):day(d), month(m),year(y)
{ }
void set_date(int d, int m, int y)
{
day=d;
month=m;
year=y;
}
};
void main()
{
Date d(10,10, 2003);
cout<<d; //same as operator<<(cout,d);
}
MULTIMEDIA UNIVERSITY 28
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
See another example below that overloads the >> as a friend function.
#include<iostream.h>
class Date
{
private:
int day;
int month;
int year;
public:
friend ostream &operator << (ostream&, const Date&);
friend istream &operator >> (istream&, Date&);
Date()
{
day=month=year=0;
}
Date(int d, int m, int y):day(d), month(m),year(y)
{ }
void set_date(int d, int m, int y)
{
day=d;
month=m;
year=y;
}
};
ostream &operator << (ostream &s, const Date &c)
{ return s<<"the date is "<<c.month<<"/"<<c.day<<"/"<<c.year<<endl;
}
MULTIMEDIA UNIVERSITY 29
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
void main()
{
Date d(10,10, 2003);
cout<<d; //same as operator<<(cout,d);
Date s;
cin>>s; // same as operator>>(cin, s)
cout<<s;
}
Summary:
Function overloading is a term to define 2 or more functions with he same name that
performs different but often similar tasks. When overloading functions, the functions
having the same name should have different signatures(by having same name and
different no of arguments and type).
In C++, it’s possible to define new operators that work with classes. This feature is called
operator overloading. The definition is just like an ordinary function definition except that
the name of the function consists of the keyword operator followed by the operator.
That’s the only difference, and it becomes a function like any other function, which the
compiler calls when it sees the appropriate pattern.
MULTIMEDIA UNIVERSITY 30
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7
References:
MULTIMEDIA UNIVERSITY 31