0% found this document useful (0 votes)
33 views36 pages

Cahpter 5 Operator Overloading

The document discusses operator overloading in C++. Operator overloading allows existing operators to work with user-defined types by changing their behavior when used with those types. The document provides examples of overloading unary and binary operators like increment, addition, and examples of their syntax and usage.

Uploaded by

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

Cahpter 5 Operator Overloading

The document discusses operator overloading in C++. Operator overloading allows existing operators to work with user-defined types by changing their behavior when used with those types. The document provides examples of overloading unary and binary operators like increment, addition, and examples of their syntax and usage.

Uploaded by

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

Operator overload

• Operator Overloading means making the compiler's built in


operator symbols work with classes.
• It is one of the features of Object oriented
programming which gives an extra ability to
an operator to act on a User-defined operand(Objects).
• C++ allows the overloading of operators and functions.
• A single operator or function can be used with
different classes of objects, which can simplify a
program's code.
• Overloading allows a user to control the behavior of an
operator with both user-defined and standard classes.
• Overloading operators allows you to apply existing operators to
objects of class type.
Cont’d…
• By using operator overloading we can easily access the
objects to perform any operations.
• Using operator overloading we can perform different
operations on the same operands.
• It is not limited to work only with primitive Data Type.
• An operator will act differently depending on the operands
provided.
• Operator is not limited to work only with primitive Data
Type.
• It will act differently depending on the operands provided.
Its called extesibility.
• By using this overloading we can easily access the objects
to perform any operations.
Cont’d…
• Operator overloading refers giving special meaning
to an existing operator.
• When an operator is overloaded, that operator
loses none of its original meaning. Instead, it gains
additional meaning relative to the class for which it
is defined.
• An operator is always overloaded relatively to a
user defined type, such as a class. To overload an
operator, you create an operator function.
• Most often an operator function is a member or a
friend of the class for which it is defined.
Overloading Operator: Some Restrictions
1. You cannot change the precedence of an operator.
2. The associativity cannot be changed. (For example,
the associativity of the arithmetic operator addition
is from left to right, and it cannot be changed.)
3. Default parameters cannot be used with an
overloaded operator.
4. You cannot change the number of parameters an
operator takes.
5. You cannot create new operators. Only existing
operators can be overloaded.
Cont’d…
6. The meaning of how an operator works with built-
in types, such as int, remains the same.
8. Operators can be overloaded either for objects of
the user-defined types, or for a combination of
objects of the user-defined type and objects of the
built-in type.
Cont’d…
• Operator Overloading does not allow us to alter the
meaning of operators when applied to built-in types
– one of the operands must be an object of a class
• Operator Overloading does not allow us to define new
operator symbols
– we overload those provided for in the language to have
meaning for a new type of data...and there are very
specific rules!
Cont’d…
• All arithmetic, bitwise, relational, equality, logical, and compound
assignment operators can be overloaded.
• In addition, the address-of, dereference, increment, decrement, and
comma operators can be overloaded.
• Operators that cannot be overloaded include:
:: scope resolution operator
. direct member access operator
.* direct pointer to member access operator
?: conditional operator
sizeof size of object operator
• Operators that must be overloaded as members:
= assignment operator
[] subscript operator
() function call operator
-> indirect member access operator
->* indirect pointer to member access operator
Cont’d…
• Unary operators declared as member functions take no
arguments; if declared as global functions, they take one
argument.
• Binary operators declared as member functions take one
argument; if declared as global functions, they take two
arguments.
• If an operator can be used as either a unary or a binary operator
(&, *, +, and -), you can overload each use separately.
• Overloaded operators cannot have default arguments.
• All overloaded operators except assignment (operator=) are
inherited by derived classes.
• The first argument for member-function overloaded operators is
always of the class type of the object for which the operator is
invoked (the class in which the operator is declared, or a class
derived from that class). No conversions are supplied for the first
Syntax of Operator Overloading

Return_type operator Symbol()


{
Body of a function;
}
Return_type: It shows the value returned by the member
function.
Operator: It is the keyword used for overloading an operator.
Symbol: The symbol of the required operator.
For Example:-
Void operator ++()
{
Function body;
}
Unary operators in C++

• These are the type of operators which works with


the single operand. These operators are overloaded
in order to enhance their capabilities.
• Following unary operators can be overloaded in C++
language:
+, -, *, ! , ~, &, ++, –, (), ->, new, delete
• The unary operators operate on the object for
which they were called and normally, this operator
appears on the left side of the object, as in !obj, -
obj, and ++obj but sometime they can be used as
postfix as well like obj++ or obj--.
Cont’d…
#include <iostream>
Using namespace std;
class Team
{
private:
int players;
public:
Team()
{
players=0;
}
void show_players()
{
cout<<"Number of players= "<<players<<"\n"<<endl;
}
void operator ++()
{
players= players+1;
}
};
int main()
{
Team t1;
cout<<"Number of Players before Increment : "<<endl;
t1.show_players();
++t1;
cout<<"Number of Players after Increment : "<<endl;
t1.show_players();
return 0;
}
Binary Operators Overloading
• The unary operators take two arguments and following are
the examples of Binary operators. You use binary operators
very frequently like addition (+) operator, subtraction (-)
operator and division (/) operator.
• The below code will overload the binary ‘+’ operator, so that
we could use it with the objects of a class Addition.
• When we add the two objects by this operator then the
object left to the binary operator will be act as a calling
function and the object at right will be act as a called
function.
• Therefore the right object will be passes as a parameter to
the left object, therefore operations will performed and the
returned object will be stored in a third object, present at
the right side of assignment operator.
Cont’d…
#include <iostream.h> Addition operator +(Addition t)
class Addition {
{ t.w1= t.w1 + w1;
private: t.w2= t.w2 + w2;
int w1, w2; return t;
public: }
Addition() };
{ int main()
w1=w2=0; {
} Addition obj1;
void input() Addition obj2;
{ Addition obj3;
cout<<"enter first value: "; obj1.input();
cin>>w1; obj2.input();
cout<<"enter Second value: "; obj3 = obj1 + obj2;
cin>>w2; obj1.show();
} obj2.show();
void show() cout<<"\nAfter adding the contents of objects the
{ values are: "<<endl;
cout<<"First value ="<<w1<<endl; obj3.show();
cout<<"Second value ="<<w2<<endl; return 0;
Overloading increment (++) Operator:-

• This is a type of unary operator, it only works with


single operand.
• By default it only work for the numeric values, it
increases there value by 1. Increment operator
works in two types of notations prefix and postfix.
In below examples we will overload both in order to
illustrate there use with user-defined data types.
#include<iostream.h>
Cont’d…
z= ++z;
class UnaryOp }
{
public: };

int x,y,z; int main()


{
UnaryOp()
{ UnaryOp u1(10,11,12);
x=0;
y=0; cout<<"\n\nNumbers are :::\n";
z=0;
} u1.display();

UnaryOp(int a,int b,int c) ++u1; // call pre increment operator function


{
x=a; cout<<"\n\nNumbers are after applying overloaded pre increment
y=b; (++) operator :::\n";
z=c;
} u1.display(); // display u1

void display() u1++; // call post increment operator function


{
cout<<"\n\n\t"<<x<<" "<<y<<" "<<z; cout<<"\n\nNumbers are after applying overloaded post increment
} (++) operator :::\n";

// overloaded increment (++) operator u1.display(); // display u1


UnaryOp operator++()
{ return 0;
x= ++x; }
Cont’d…
#include <iostream.h>
class Team
{
private:
int players;
public:
Team()
{
players=0;
}
void show_players()
{
cout<<"Number of players= "<<players<<"\n"<<endl;
}
void operator ++()
{
players= players+1;
}
};
int main()
{
Team t1;
cout<<"Number of Players before Increment : "<<endl;
t1.show_players();
++t1;
cout<<"Number of Players after Increment : "<<endl;
t1.show_players();
return 0;
Overloading Postfix Increment Operator

#include <iostream.h>
class Team
{
private:
int players;
public:
Team()
{
players=0;
}
void show_players()
{
cout<<"Number of players= "<<players<<endl;
}
// for postfix notation
void operator ++(int)
{
players= players+1;
}
};
int main()
{
Team t1;
t1.show_players();
t1++;
t1.show_players();
return 0;
Example of Overloading both increment notations in a same program

#include <iostream.h> }
class Team // for postfix notation
{ void operator ++(int)
private: {
int players; players= players+1;
public: }
Team() };
{ int main()
players=0; {
} Team t1;
void show_players() t1.show_players();
{ ++t1;
cout<<"Number of players= "<<players<<endl; t1.show_players();
} t1++;
// For prefix notation t1.show_players();
void operator ++() return 0;
{ }
Overloading comparison operator in C++

The comparison operator (==) is used to compare the


value of two objects. It cannot be used with user-
defined data types but it could be overloaded in
order to use it with them.
#include <iostream.h>
Cont’d…
if(strlen(s.st) == strlen(st) )
#include <string.h> return 1;
class test else
{ return 0;
private: }
char st[50]; };
public: int main()
test() {
{ test s1,s2;
st[0] = '\0'; s1.in();
} s2.in();
void in() cout<<"\ns1 = ";
{ s1.show();
cout<<"Enter String: "; cout<<"s2 = ";
cin>>st; s2.show();
} if(s1 == s2)
void show() cout<<"\nBoth strings are of equal length. ";
{ else
cout<<st<<endl; cout<<"\nBoth strings are of different length. ";
} return 0;
int operator == (test s) }
Example of Overloading both increment notations in a same program:-

#include <iostream.h> }
class Team // for postfix notation
{ void operator ++(int)
private: {
int players; players= players+1;
public: }
Team() };
{ int main()
players=0; {
} Team t1;
void show_players() t1.show_players();
{ ++t1;
cout<<"Number of players= "<<players<<endl; t1.show_players();
} t1++;
// For prefix notation t1.show_players();
void operator ++() return 0;
{ }
Assignment Operators Overloading
• You can overload the assignment operator (=) just
as you can other operators and it can be used to
create an object just like the copy constructor.
Cont’d…
#include <iostream> inches = D.inches;
using namespace std; }
class Distance // method to display distance
{ void displayDistance()
private: {
int feet; // 0 to infinite cout << "F: " << feet << " I:" << inches << endl;
int inches; // 0 to 12 }
public: // required constructors };
Distance() int main()
{ {
feet = 0; Distance D1(11, 10), D2(5, 11);
inches = 0; cout << "First Distance : ";
} D1.displayDistance();
Distance(int f, int i){ cout << "Second Distance :";
feet = f; D2.displayDistance();
inches = i; // use assignment operator
} D1 = D2;
void operator=(const Distance &D ) cout << "First Distance :";
{ D1.displayDistance();
Type cast operator
• A cast is a special operator that forces one data type
to be converted into another.
• As an operator, a cast is unary and has the same
precedence as any other unary operator.
• The most general cast supported by most of the C+
+ compilers is as follows:
(type) expression
Where type is the desired data type. There are other
casting operators supported by C++, they are listed
below:
Cont’d…
1. const_cast<type> (expr): The const_cast operator is used to
explicitly override const and/or volatile in a cast. The target type
must be the same as the source type except for the alteration of its
const or volatile attributes. This type of casting manipulates the
const attribute of the passed object, either to be set or removed.
2. dynamic_cast<type> (expr): The dynamic_cast performs a runtime
cast that verifies the validity of the cast. If the cast cannot be made,
the cast fails and the expression evaluates to null. A dynamic_cast
performs casts on polymorphic types and can cast a A* pointer into
a B* pointer only if the object being pointed to actually is a B object.
3. reinterpret_cast<type> (expr): The reinterpret_cast operator
changes a pointer to any other type of pointer. It also allows casting
from pointer to an integer type and vice versa.
4. static_cast<type> (expr): The static_cast operator performs a
nonpolymorphic cast. For example, it can be used to cast a base
class pointer into a derived class pointer.
Cont’d…
#include <iostream.h>
main()
{
double a = 21.09399;
float b = 10.20;
int c ;
c = (int) a;
cout << "Line 1 - Value of (int)a is :" << c << endl ;
c = (int) b;
cout << "Line 2 - Value of (int)b is :" << c << endl ; return
0;
Subscripting [] operator overloading in C++

• The subscript operator [] is normally used to access


array elements. This operator can be overloaded to
enhance the existing functionality of C++ arrays.
• Following example explains how a subscript
operator [] can be overloaded.
Cont’d…
#include <iostream.h> {
const int SIZE = 10; cout << "Index out of bounds" <<endl;
// return first element.
class array return arr[0];
{ }
private: return arr[i];
int arr[SIZE]; }
public: };
array() int main()
{ {
register int i; array A;
for(i = 0; i < SIZE; i++)
{ cout << "Value of A[2] : " << A[2] <<endl;
arr[i] = i; cout << "Value of A[5] : " << A[5]<<endl;
} cout << "Value of A[12] : " << A[12]<<endl;
}
int &operator[](int i) return 0;
{ }
if( i > SIZE )
Subscripting () operator overloading in C++
#include <iostream.h> return *this;
class myclass }
{ void myclass::show()
int a,b; {
public: cout<<a<<endl<<b<<endl;
myclass(){} }
myclass(int,int); // --- MEMBER FUNCTIONS ---
myclass operator()(int,int); // ------------------------
void show(); void main()
}; {
// ------------------------ myclass ob1(10,20);
// --- MEMBER FUNCTIONS --- myclass ob2;
myclass::myclass(int x, int y) ob1.show();
{ // it's a nice way to pass
a=x; // values, otherwise we
b=y; // would have to define and
} // call a member/friend function
myclass myclass::operator()(int x, int y) // to do so
{ ob2(100,200);
a=x; ob2.show();
b=y; }
Cont’d…
#include <iostream.h> temp.y = y + b;
class MyClass { temp.z = z + c;
int x, y, z; return temp;
public: }
MyClass() { void MyClass::show()
x = y = z = 0; {
} cout << x << ", ";
MyClass(int i, int j, int k) { cout << y << ", ";
x = i; cout << z << endl;
y = j; }
z = k; int main()
} {
MyClass operator()(int a, int b, int c); MyClass object1(1, 2, 3), object2;
void show() ; object2 = object1(10, 11, 12); // invoke
}; operator()
// Overload (). cout << "object1: ";
MyClass MyClass::operator()(int a, int b, int c) object1.show();
{ cout << "object2: ";
MyClass temp; object2.show();
temp.x = x + a; return 0;
Input/Output operators overloading in C++
• C++ is able to input and output the built-in data types using
the stream extraction operator >> and the stream insertion
operator <<.
– Input data is replaced by >>
– display is replaced by <<
– assign or copy is replaced by =
• The stream insertion and stream extraction operators also
can be overloaded to perform input and output for user-
defined types like an object.
• Here, it is important to make operator overloading function
a friend of the class because it would be called without
creating an object.
• Following example explains how extraction operator >> and
Cont’d…
#include <iostream.h> friend istream &operator>>( istream &input, Distance &D )
class Distance {
{ input >> D.feet >> D.inches;
private: return input;
int feet; // 0 to infinite }
int inches; // 0 to 12 };
public: int main()
// required constructors {
Distance(){ Distance D1(11, 10), D2(5, 11), D3;
feet = 0;
inches = 0; cout << "Enter the value of object : " << endl;
} cin >> D3;
Distance(int f, int i){ cout << "First Distance : " << D1 << endl;
feet = f; cout << "Second Distance :" << D2 << endl;
inches = i; cout << "Third Distance :" << D3 << endl;
} return 0;
friend ostream &operator<<( ostream &output, }
const Distance &D )
{
output << "F : " << D.feet << " I : " << D.inches;
return output;
}
Shallow copy
• A shallow copy of an object copies all of the
member field values.
• This works well if the fields are values, but may not
be what you want for fields that point to
dynamically allocated memory.
• The pointer will be copied. but the memory it points
to will not be copied -- the field in both the original
object and the copy will then point to the same
dynamically allocated memory, which is not usually
what you want.
• The default copy constructor and assignment
operator make shallow copies.
Cont’d…
class Employee
{
public:
char* name;
char dept[10];
};

int main()
{
Employee a;
a.name=new char[10];
strcpy(a.name, "spiderman");
strcpy(a.dept,"IT");

//Root cause of shallow copy: Using default copy constructor


Employee b(a);
cout<<b.name << " "<<b.dept<<" ";

//Problem of shallow copy


strcpy(b.name, "batman" );
cout<<b.name << " "<<a.name<<" ";

//Root cause of shallow copy: Using default assignment operator


Employee c=a;

//Problem of shallow copy


strcpy(c.name, "superman" );
cout<<a.name << " "<<b.name << " "<<c.name<<" ";
Deep copy
• A deep copy copies all fields, and makes copies of
dynamically allocated memory pointed to by the
fields.
• To make a deep copy, you must write a copy
constructor and overload the assignment operator,
otherwise the copy will point to the original, with
disasterous consequences.
• If an object has pointers to dynamically allocated
memory, and the dynamically allocated memory
needs to be copied when the original object is
copied, then a deep copy is required.
• A class that requires deep copies generally needs:
Cont’d…
• A constructor to either make an initial allocation or
set the pointer to NULL.
• A destructor to delete the dynamically allocated
memory.
• A copy constructor to make a copy of the
dynamically allocated memory.
• An overloaded assignment operator to make a copy
of the dynamically allocated memory.

You might also like