[go: up one dir, main page]

0% found this document useful (0 votes)
16 views31 pages

Chapter 7

Uploaded by

athilahnurin03
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views31 pages

Chapter 7

Uploaded by

athilahnurin03
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 31

DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7

LECTURE 7

Function Name and Operator Overloading

Objective

At the end of this lecture, students should be able to:

 Understand what is overloaded functions and operators


 Explain the benefits of overloading
 Explain the rules that apply to operator overloading
 Create overloaded functions and operators in classes
 Overload the math operators
 Overload the prefix and postfix ++ and – operators
 Overload the = operator
 Overload the insertion (<<) operator for output
 Overload the extraction (>>) operator for input

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

float f(int, float)


float f(float, int)
 The C++ compiler keeps track of different same name functions. When an overloaded
function is called, the program examines the input and return data types in the call
statement and accesses the correct function.
 See an example below where there are multiple forms of AddAndDisplay function with
different parameter declaration.
 Notice that overloaded function has different signatures. A functions’s signature consists
of:
o Its name
o The number, data types and order or its arguments
 To be distinct, functions must have distinct signatures.

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);

AddAndDisplay(m,n); // will call function with prototype


// void AddAndDisplay(double,double);

AddAndDisplay(x,y); // will call function with prototype


// void AddAndDisplay(float,float);
}

// Sample code for function overloading


void AddAndDisplay(int x, int y)
{

MULTIMEDIA UNIVERSITY 3
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7

cout<<" Integer result: "<<(x+y)<<endl;


}

void AddAndDisplay(double x, double y)


{
cout<< " Double result: "<<(x+y)<<endl;
}

void AddAndDisplay(float x, float y)


{
cout<< " float result: "<<(x+y)<<endl;

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

2.1 Overriding and Overloading Parent Class Functions


 In this part of the chapter we will examine how a child class may overload or override
a parent class.

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

Example 1: A child using parent’s function

#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;}
};

class Derived : public Base {


protected: int ddm;
public:
Derived( ):Base( ){ ddm=0;}
Derived(int i):Base(i), ddm (i) { }
~Derived( ) { }

};

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

Example 2: A child class having an overloaded function

#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; }

};
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(int i):Base(i), ddm (i) { }

~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 is perhaps the most interesting of the three options.

 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

Example 3: Overriding class member functions


#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;
}
};

class Derived : public Base {


protected: int ddm;
Same name:
public:
Override
Derived( ):Base( ){ ddm=0;}
Derived(int i):Base(i), ddm (i) { }
~Derived( ) { }
void Display()
{
cout<<"Base::bdm:"<<bdm<<endl;
cout<<"Derived::ddm:"<<ddm<<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;
}

};

void main( ) { Output:


Base b_obj;
Base::bdm:0
Derived d_obj(4);
b_obj.Display(); Base::bdm:4

d_obj.Display(); Base::bdm:4
} Derived::ddm:4

Press any key to continue

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& add(MyString val)


{
strcat(word1, val.word1);
return *this;
}

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

Example 2: Overloading the + to concatenate string of the objects

#include<iostream>
#include<string>
using namespace std;

class MyString
{
private: char word1[100];
public:

MyString& operator +(MyString val)


{
strcat(word1, val.word1);
return *this;
}

MyString(char s[])
{
strcpy(word1, s);
}

MyString()
{
strcpy(word1,"Hello");
}

char* getString()
{
return word1;
}
};

void main( ) { s1 is the invoking object that


MyString s1; makes a call to operator+ (..)
MyString s2("World");
s1=s1+s2;
cout<<s1.getString()<<endl;

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

Original code Substituted code

MyString& add(MyString val) MyString& operator +(MyString val)


{ {
strcat(word1, val.word1); strcat(word1, val.word1);
return *this; return *this;
} }

 Here is the syntax for overloaded operators, where op is the operator being overloaded:

return_type operator op (parameter list)


{ //statements }

2.1 Rules for Operator overloading

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

 There are 5 operators that CANNOT be overloaded:

Operator Usual Use


. (dot operator) member selection
*. pointer to member
:: scope resolution
?: conditional
sizeof size of

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

2.2 Overloading binary Math Operators(+, -, *)


 To overload the math operators, you need to create an operator function, as in:
operator+().
 In the example above(with a class MyString), the + operator is overloaded.
 Below is another example of overloading with some math operators like +, - , *, etc.

Example: without overloading (add, subtract, multiply)


#include<iostream.h>
class Point{
private: double x, y;
public:
Point()
{
x=y=0.0;
}

Point(double n1, double n2)


{

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

Example: with overloading (operator+, operator -, operator*)

#include<iostream.h>

class Point{
private: double x, y;
public:
Point()
{
x=y=0.0;
}

Point(double n1, double n2)


{
x=n1;
y=n2;
}

Point operator + (const Point &p)


{
return Point(x + p.x, y + p.y) ;
}

Point operator - (const Point &p)


{
return Point(x - p.x, y - p.y) ;
}

Point operator * (const Point &p)


{
return Point(x * p.x, y * p.y) ;
}

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.

 Using the example above (overloading the +):


p3=p1 + p2;
Point operator + (const Point &p)
{
return Point(x + p.x, y + p.y) ;
}
New object is returned and copied to p3

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

 The statement: return Point(x + p.x, y + p.y) ;

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.

• For p++, an object is returned before incrementing occur.

• A similar procedure is exercised for the prefix and postfix decrement operators.

• Below is an example of a class that uses overloaded ++ and --.

• In the example below, the statement :r = ++p1;

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.

• In the example below, the statement :r = p2++;

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(int n1, int n2)


{
x=n1;
y=n2;
}

Point Point::operator ++ ( )
{
++x;
++y;
return Point(x, y);
}

Point Point::operator ++ (int)


{

return Point(x++, y++);


}

Point Point::operator -- ( )
{
--x;
--y;
return Point(x, y);
}

Point Point::operator -- (int)


{

return Point(x--, y--);


}
Output:

void Point::display() r=++p1 =


x : 3
{ y : 4
cout<<"x : "<<x<<endl;
r=p2++ =
cout<<"y : "<<y<<endl<<endl; x : 2
} y : 3

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 = ++p1; //++p1 can be written as p1.operator++();


cout<<"r=++p1 ="<<endl;
r.display();

r =p2++;
cout<<"r=p2++ ="<<endl;
r.display();
p2.display();
cout<<endl;
}

2.4 Overloading the binary assignment (= )operator


• The operation of the overloaded assignment operator = ( ) function is similar to the
operation of the copy constructor.

Example:

#include<iostream.h>
class Point{
private: double x, y;
public:
Point();
Point(double, double);
void display();
Point operator = (const Point &p);
};

Point Point::operator = (const Point &p){


x = p.x; y = p.y;
cout<<"Overloaded = operator called"<<endl;
return Point(x, y);
}

Point::Point()
{
x=y=0;
}

MULTIMEDIA UNIVERSITY 20
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7

Point::Point(double n1, double n2)


{
x=n1;
y=n2;
}

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

Overloaded = operator called


p2=p1; // same as p2.operator=(p1); p2 = p1, Result...
cout<<"p2 = p1, Result..."<<endl; p1 object
x : 3
cout<<"p1 object "<<endl; y : 4
p1.display();
p2 object
cout<<"p2 object "<<endl; x : 3
p2.display(); y : 4

Press any key to continue


}

 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

2.5 Non-Member Overloaded Operator Functions

• Overloaded operator functions can be non-member functions or friend functions

2.5.1 Non-Member and operator overloading function


Example:
#include<iostream.h>
class Point{
private: double x, y;
public:
Point();
Point(double, double);
void display();
double getX();
double getY();
};

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

Point operator + (Point p1, Point p2){


return Point ( p1.getX() + p2.getX(), p1.getY() + p2.getY() );
}
Point operator - (Point p1, Point p2){
return Point ( p1.getX() - p2.getX(), p1.getY() - p2.getY() );
}

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

p3.display(); Press any key to continue


p4.display();
}

 Based on the above program, example at the statement in main(): p3= p1 + p2


The expression p1 + p2 is a calling function to the function having the header :

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.

p1 + p2 is an operator overloaded calling function that is rewritten for


operator+(p1,p2)

 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

2.5.2 friends and operator overloading function


Example: Operator overloading function as friend of a class (similar to the above example for
non-member function)

#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;
}

Point operator + (Point p1, Point p2){


return Point ( p1.x + p2.x, p1.y + p2.y ); Notice that the private data
} members x, y can be accessed
directly in the friend operator
Point operator - (Point p1, Point p2){ overloaded functions
return Point ( p1.x - p2.x, p1.y - p2.y );
}

void main( ){
Point p1(3.0, 4.0);
Point p2(1.0, 2.0);

MULTIMEDIA UNIVERSITY 24
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7

Point p3, p4;

p3 = p1 + p2;
p4 = p1 - p2;

p3.display();
p4.display();
}

2.6 Overloading Input Extraction(>>) and Output Insertion(<<) Operators


 The two I/O operators- insertion (<<) and extraction (>>) are frequently overloaded
enabling us to input and output data belonging to the objects of our own class type.
 Overloaded insertion and extraction functions must be non-member functions of a user-
defined class.
 One of the advantages of using the iostream objects is that you can customize them to
support your own classes.
 For example, whenever we want to output the values of the data members stored in a
Date object, ex. Output the date; we would have to write:
cout<<date1.get_month()<<”/”<<date1.get_day()<<”/”<<date1.get_year();
Example output:
10/10/2003

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 set_date(int d, int m, int y)


{
day=d;
month=m;
year=y;
}
int get_day(){ return day;}
int get_month(){ return month;}
int get_year(){ return year;}

};

void main()
{
Date date1(10,10, 2003);
cout<<date1.get_month()<<"/"<<date1.get_day()<<"/"<<date1.get_year();
}

 If the insertion operator is overloaded, we can just write:


cout<<date1;
This will also produce a similar output also if the << operator is overloaded

Example: Overloading << operator


#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 26
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7

void set_date(int d, int m, int y)


{
day=d;
month=m;
year=y;
}
int get_day(){ return day;}
int get_month(){ return month;}
int get_year(){ return year;}

};

ostream& operator<<(ostream& output, const Date &d)


{
return output<<"the date is
"<<d.get_month()<<"/"<<d.get_day()<<"/"<<d.get_year()<<endl;
}
Output:
void main()
{ the date is 10/10/2003
Date d(10,10, 2003); Press any key to continue
cout<<d; //same as operator<<(cout,d);
}

 How to overload the insertion(<<) operator? :


o The function must be a friend or non-member function because the left
parameter(cout) is not of the class type.
o The overloaded << returns a reference to an ostream object and takes two
parameters by reference: an ostream object and a user-defined type. The user-
defined type is passed as a const parameter because the output operation
doesn't modify it.
o It must also return a reference to ostream.

 In the example above cout<<d makes a call to ostream& operator<<(ostream&


output, Date &d) which is a non-member of class Date

 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

Example: Overloading << operator and friend

#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;
}

};

ostream &operator << (ostream &s, const Date &c)


{
return s<<"the date is "<<c.month<<"/"<<c.day<<"/"<<c.year<<endl;
}

void main()
{
Date d(10,10, 2003);
cout<<d; //same as operator<<(cout,d);
}

MULTIMEDIA UNIVERSITY 28
DCS 5088 OBJECT ORIENTED PROGRAMMING LECTURE 7

 The extraction(>>) operator is overloaded in a similar way. Difference is that we need to


use the istream object in the overloaded functions.

o The function must be a friend or non-member function because the left


parameter(cin) is not of the class type.
o The overloaded >> returns a reference to an istream object and takes two
parameters by reference: an istream object and a user-defined type. Don’t use
const reference for the user-defined type because the object is going to be
modified with user input.
o It must also return a reference to istream.

 See another example below that overloads the >> as a friend function.

Example: Friends and operator overloading >> and << functions

#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

istream &operator >> (istream &in,Date &c)


{
cout<<"Enter month, day and year :"<<endl;
return in>>c.month>>c.day>>c.year;
}

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;
}

the date is 10/10/2003


Output:
Enter month, day and year :
8 8 2005
the date is 8/8/2005
Press any key to continue

Summary:

 C++ allows function overloading and operator overloading.

 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:

1. Timothy B. D’Orazio, Programming in C++, McGraw-Hill, 2004


2. Richard Johnsonbaugh, Martin Kalin, Object-oriented programming in C++, 2/e, Prentice
Hall, 2000
3. http://www.codersource.net/codersource_cppprogramming.html
4. http://cplus.about.com/od/beginnerctutorial/l/aa101302a.htm
5. http://cplus.about.com/od/beginnerctutorial/l/aa061602a.htm

MULTIMEDIA UNIVERSITY 31

You might also like