100% found this document useful (1 vote)
66 views

SN Operator Overloading in C++ II 2023

This document discusses operator overloading in C++. It explains that operator overloading allows existing operators like + and - to work with user-defined types like complex numbers and matrices. This is done by defining special operator functions within the class. For binary operators like -, these functions can be member functions or friend functions. For unary operators like -, only member or friend functions can be used. Examples are provided to demonstrate overloading operators like +, -, << for complex number arithmetic and matrix operations to allow natural syntax like a + b rather than function calls.

Uploaded by

Sai Praneeth
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
66 views

SN Operator Overloading in C++ II 2023

This document discusses operator overloading in C++. It explains that operator overloading allows existing operators like + and - to work with user-defined types like complex numbers and matrices. This is done by defining special operator functions within the class. For binary operators like -, these functions can be member functions or friend functions. For unary operators like -, only member or friend functions can be used. Examples are provided to demonstrate overloading operators like +, -, << for complex number arithmetic and matrix operations to allow natural syntax like a + b rather than function calls.

Uploaded by

Sai Praneeth
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 29

CSC 404 Object Oriented Programming

Dept. of Comp. Sc. & Engg., NIT Durgapur

Operator Overloading in C++ - II


- [email protected]

“Operator overloading is just syntactic sugar, which means it is simply another way for a
user to make a function call” – Bruce Eckel (Thinking in C++, Vol 1)
Recap……

CS 404; OOPS (Opeartor Overloading)


[email protected]
Overloading of operators…
float x, y, c;
int a, b, c;
+ and << are binary operators
a = b + c; // + adds two integers
x = y + z; // + adds two float variables & is an unary operator
b = a<<1; // << acts as bit-wise left shift operator
cout<<a<<b; // << acts as insertion operator
a = b & c; // & acts as bit-wise AND operator
int *p = &a; // & acts as address-of operator

Many of the existing C++ operators are already overloaded for built-in datatypes;
Overload means assign multiple responsibilities based on the context

Can this overloading feature be extended to


user-defined data types (class) also?
CS 404; OOPS (Opeartor Overloading)
[email protected]
Operator overloading…
complex a, b, c;
a = b.AddComplex(b); a = b + c;
b = a.IncComplex(); b = ++a;

matrix p, q, r;
p = q.AddMatrix(q); p = q + r; Easier to read
r = p.InvMatrix(); r = ~p;
cout<<p<<q<<r;

• Operator overloading is an object-oriented feature


• to assign more responsibility to existing C++ operators (e.g.: ‘+’, ‘++’, ‘~’, etc.)
• so that they can work meaningfully with user-defined class (e.g.: complex, matrix, stack, etc.) objects;
• the way they work in association with built-in class (e.g: int/float, etc.) objects

• It just makes the code involving your class easier to read.


CS 404; OOPS (Opeartor Overloading)
[email protected]
Overloading Binary operators: Points to note
• Use of an overloaded binary operator (‘-’) with user-defined objects (a and b)
gets translated to a special operator function call with the name operator@; @ being the name of the overloaded operator (e.g.: operator-)

Overloading Operator Options Compiler translation


Syntax Function name
i
a - b; i) Member function a.operator-(b); One can add both the options
ii) Friend function operator-(a,b); simultaneously;
operator- Availability of member function is
a - 3.0; i) Member function a.operator-(3.0)
checked first if not found only then
ii) Friend function operator-(a,3.0); it searches for friend option
3.0 - b; Friend function operator-(3.0,b);

• To make it possible
The behavior of the operator function need to be defined in the class definition
a binary operator function takes one argument (the 2 nd operand) when implemented as member function
a binary operator function takes two arguments (1 st operand and 2nd operand) when implemented as friend function

• Difference with function call


function don’t appear inside parentheses (e.g.: d=a.SubComplex(b)), but instead
surrounded or are next to characters (e.g.: d = a - b or a++) – a syntactic sugar; just another way of calling a function
CS 404; OOPS (Opeartor Overloading) [email protected]
Addition of Complex objects: using SubComplex() method

class complex
{ int main(void)
float rl, img; // private members {
public: complex a, b(2,3.5),d;
float arg, amp;
complex(float f1=1.0,float f2=1.0) {..} // subtracting two complex objects
~complex() {}
// other required methods……… d = a.SubComplex ( b );

//body of the special operator function


complex & SubComplex (const complex &c)
Note:
{
static complex t; // local object to store diff • Instead of call by value use call by const object
t.rl = rl - c.rl; // OR t.rl = this.rl – c.rl return 0; reference; to avoid overhead of temporary object
t.img = img - c.img; } constr/destruction
return t; • Instead of returning value of the object from function
} return object reference; make sure the object to be
}; // End of class definition returned exists (for local object declare it static) even
outside the function

CS 404; OOPS (Opeartor Overloading) [email protected]


class complex
{ float rl, img; //body of the special operator function; CASE 1
public: complex & complex:: operator-(const complex &c) int main(void)
float arg, amp; { {
static complex t; complex a, b(2,3.5);
complex(float f1=1.0,float f2=1.0) {..}
~complex() {} t.rl = rl - c.rl; complex d;
// other required methods……… t.img = img - c.img;
return t; d = a.SubComplex(b);
complex & SubComplex(const complex &c); }
d=a-b;
//body of the special operator function; CASE 2 d = a - 3.0 ;
//prototype of the operator functions complex & operator+(const complex &c, float x) d = 4.5 - b;
complex & operator+(const complex &c); {
static complex t; return 0;
friend complex & operator+(const complex &c, float x); }
friend complex & operator+(float x, const complex &c); t.rl = rl - x;
t.img = img;
return t;
}; // End of class definition } Putting all possible
// body of friend operator function; CASE 3 options together for
complex & operator-(float x, const complex &c) ‘-’ operator in the
// body of SubComplex method { class definition….
complex & complex:: SubComplex(const complex &c) static complex t;
{ t.rl = c.rl - x;
static complex t; t.img = c.img; Opting for friend
t.rl = rl - c.rl; return t; function instead of
t.img = img - c.img; } member function for
return t; the case a - 3.0
}
CS 404; OOPS (Opeartor Overloading) [email protected]
Overloading Unary operators

CS 404; OOPS (Opeartor Overloading) [email protected]


Overloading Unary operators: Points to note
• Use of an overloaded unary operator (‘-’) with user-defined object
gets translated to a special operator function call with the name operator@; @ being the name of the overloaded operator (e.g.: operator-)
Overloading Operator Options Compiler translation
Syntax Function name
i - b; operator- i) Member function b.operator-()
ii) Friend function operator-(b);

• An unary operator function takes either no arguments (member function) or one argument (friend function)
• Overloading increment (++) and decrement (--) operators
Overloading Operator Function Options Operator function call
Syntax name
++a operator++ i) Member function a.operator++()
ii) Friend function operator++(a);
a++ operator++ i) Member function a.operator++(int)
dummy int argument is
passed to post-inc/dec to
ii) Friend function v int);
operator++(a,
distinguish it from
--a operator- - i) Member function a.operator- -()
pre-inc/dec case
ii) Friend function operator- -(a);
a-- operator- - i) Member function a.operator- -(int)
ii) Friend function operator-v-(a, int);

CS 404; OOPS (Opeartor Overloading) [email protected]


> to be members. It seemed a harmless restriction that eliminated the possibility of some obscure errors because these operators invariably depend on and typically modify the state of their left-hand
d -> to be members. It seemed a harmless restriction that eliminated the possibility of some obscure errors because these operators invariably depend on and typically modify the state of their left-ha

Overloadable operators…
and -> to be members. It seemed a harmless restriction that eliminated the possibility of some obscure errors because these operators invariably depend on and typically modify the state of their left-

• Except existing operators no new operators like +-, ^^, ^% can be overloaded

• Operators that can be overloaded:


+ - * / % & | ~ = += -= *= /= %= && || ++ -- >> << <<= >>= == != > < <= >= ( ) [ ] ->* -> new
delete
• Operators that cannot be overloaded: sizeof, .* (member access through poniter to member)
. (member access) - difficult to infer if it is for object reference or overloading
:? (ternary conditional) - difficult to implement that either exp2 or exp3 be executed when overloaded like exp1 ? exp2 : exp3
:: (scope resolution) – performs compile time scope resolution rather than an expression evaluation

• The arity, precedence and associativity of the operators cannot be changed

• Operators , || && when overloaded losses their special properties (short-circuit evaluation and sequencing); better to avoid
overloading them

• Operators = [] () cannot be overloaded using friend function;


“harmless restriction that eliminated the possibility of some obscure errors because these operators invariably depend on and modify the state of
their left-hand operand. However it is probably the case of unnecessary nannyism …..” Bjarne Stroustrup
CS 404; OOPS (Opeartor Overloading) [email protected]
Some interesting overloading cases….

<< >> (insertion and extraction operator)


[] (subscript or array index operator)
= (assignment operator)
new
delete (memory allocation/deallocation op)

CS 404; OOPS (Opeartor Overloading) [email protected]


Overloading << & >> operator

• The new and delete operators can also be overloaded like other operators in C++
complex a, b;
cout<<a;

• Options
(i) member function - cout.operator<<(a) // NOT possible to include operator<< in ostream class
(ii) friend function - operator<<(cout,a) // ONLY OPTION is to implement a friend operator function

CS 404; OOPS (Opeartor Overloading)


[email protected]
Overloading << & >> operator

CS 404; OOPS (Opeartor Overloading)


[email protected]
Overloading subscript operator []
• Generally used with arrays to retrieve and manipulate the array elements

• Probable usuage of overloading of []


• check for index out of bound which otherwise might generate run-time errors
• referring linked list elements using index noation (e.g.: linked_list a; int x=a[3]; // storing 3 rd node info of an
integer linked list

CS 404; OOPS (Opeartor Overloading)


[email protected]
Overloading assignment operator =

CS 404; OOPS (Opeartor Overloading)


[email protected]
Overloading = (binary) assignment operator

class complex
{ int main(void)
{
float rl, img;
public: int x, y=2;
float arg, amp;
complex(float f1=1.0,float f2=1.0) {..} x=y;
~complex() {}
float a, b=3.0;

// no operator function overloaded a=b;

}; // End of class definition


complex a, b(2,3.5);
Works even if operator = has not been
a=b; // Works overloaded for user-defined class
complex; SEEMS STRANGE

Here compiler provides a free options


that implements shallow (bitwise)
copying
return 0;
}

CS 404; OOPS (Opeartor Overloading) [email protected]


Overloading = (binary) assignment operator
Let’s add a pointer var Stack Heap
as an addition member; segment segment
class complex constructor modified
{ int main(void)
float rl, img, {
float *prt; // pointer member complex a;
public: rl=1.0, img=1.0
float arg, amp; { a ptr=
complex(float f1=1.0,float f2=1.0) complex b(2.0,3.5);
{
rl=f1; img=f2; a=b;
ptr = new float(ri+img); // dy alloc from heap }
}
~complex()
{ return 0;
delete ptr; // deloc from heap }
}

// no operator function overloaded


}; // End of class definition

CS 404; OOPS (Opeartor Overloading) [email protected]


Overloading = (binary) assignment operator
Stack Heap
segment segment
class complex
{ int main(void)
float rl, img, { 1050 2.0
float *prt; // pointer member complex a;
public: rl=1.0, img=1.0
float arg, amp; { a ptr=1050
complex(float f1=1.0,float f2=1.0) complex b(2.0,3.5);
{
rl=f1; img=f2; a=b;
ptr = new float(ri+img); // dy alloc from heap }
}
~complex()
{ return 0;
delete ptr; // deloc from heap }
}

// no operator function overloaded


}; // End of class definition

CS 404; OOPS (Opeartor Overloading) [email protected]


Overloading = (binary) assignment operator
Stack Heap
segment segment
class complex
{ int main(void)
float rl, img, { rl=2.0, img=3.5 1050 2.0
complex a; b ptr=
float *prt; // pointer member
public: rl=1.0, img=1.0
float arg, amp; { a ptr=1050
complex(float f1=1.0,float f2=1.0) complex b(2.0,3.5);
{
rl=f1; img=f2; a=b;
ptr = new float(ri+img); // dy alloc from heap }
}
~complex()
{ return 0;
delete ptr; // deloc from heap }
}

// no operator function overloaded


}; // End of class definition

CS 404; OOPS (Opeartor Overloading) [email protected]


Overloading = (binary) assignment operator
Stack Heap
segment segment
class complex
{ int main(void)
float rl, img, { rl=2.0, img=3.5 1050 2.0
complex a; b ptr=1055
float *prt; // pointer member
public: rl=1.0, img=1.0
float arg, amp; { a ptr= 1050
complex(float f1=1.0,float f2=1.0) complex b(2.0,3.5); 1055 4.5

{
rl=f1; img=f2; a=b;
ptr = new float(ri+img); // dy alloc from heap }
}
~complex()
{ return 0;
delete ptr; // deloc from heap }
}

// no operator function overloaded


}; // End of class definition

CS 404; OOPS (Opeartor Overloading) [email protected]


Overloading = (binary) assignment operator
Stack Heap
segment segment
class complex
{ int main(void)
float rl, img, { rl=2.0, img=3.5 1050 2.0
complex a; b ptr=1055
float *prt; // pointer member
public: rl=2..0, img=3.5
float arg, amp; { a ptr= 1055
complex(float f1=1.0,float f2=1.0) complex b(2.0,3.5); 1055 4.5

{
rl=f1; img=f2; a=b;
ptr = new float(ri+img); // dy alloc from heap }
}
Here, in absence of operloaded
~complex() behavior of =; Shallow bitwise
{ return 0; copying has been performed by
delete ptr; // deloc from heap } the functionality provided by
} compiler

// no operator function overloaded As a result any change made by


}; // End of class definition object a or b in location 1055 of
heap segment affects the other;
undesirable
CS 404; OOPS (Opeartor Overloading) [email protected]
Overloading = (binary) assignment operator
Stack Heap
segment segment
class complex
int main(void)
{ { 1050 2.0
float rl, img, complex a;
float *prt; // pointer member rl=2..0, img=3.5
public: { a ptr= 1055
float arg, amp; complex b(2.0,3.5); 1055 4.5

complex(float f1=1.0,float f2=1.0)


{ a=b;
rl=f1; img=f2; }
ptr = new float(ri+img); // dy alloc from heap // here b goes out of scope Destructor called as b goes out of
} scope
~complex()
{ return 0;
delete ptr; // deloc from heap }
}

// no operator function overloaded


}; // End of class definition

CS 404; OOPS (Opeartor Overloading) [email protected]


Overloading = (binary) assignment operator
Stack Heap
segment segment
class complex
int main(void)
{ { 1050 2.0
float rl, img, complex a;
float *prt; // pointer member rl=2..0, img=3.5
public: { a ptr= 1055
float arg, amp; complex b(2.0,3.5); 1055 4.5

complex(float f1=1.0,float f2=1.0)


{ a=b;
rl=f1; img=f2; }
ptr = new float(ri+img); // dy alloc from heap // here b goes out of scope OOPS!!! space pointed by b.ptr
} destructor called becomes free; as b.ptr and a.ptr
~complex() pointed to the same location; hence,
{ a.ptr now becomes a dangling pointer
delete ptr; // deloc from heap return 0;
} } Remedy don’t rely on default shallow
copy; let’s write explicitly overloaded
// no operator function overloaded
behavior of operator = so that the
}; // End of class definition assignment works consistently

CS 404; OOPS (Opeartor Overloading) [email protected]


Overloading = (binary) assignment operator
Let’s add operator=
function
class complex
{ int main(void)
float rl, img, {
float *prt; // pointer member complex a;
public:
float arg, amp;
complex(float f1=1.0,float f2=1.0) {
{ complex b(2.0,3.5);
rl=f1; img=f2;
ptr = new float(ri+img); // dy alloc from heap a=b;
} }
~complex()
{
delete ptr; // deloc from heap
} return 0;
}
void operator=(const complex &c)
{
rl=f1; img=f2;
ptr = new float(c.ri+c.img); // dy alloc create fresh copy

}; // End of class definition


CS 404; OOPS (Opeartor Overloading) [email protected]
Overloading = (binary) assignment operator
Stack Heap
segment segment
class complex
{ int main(void)
float rl, img, { rl=2.0, img=3.5 1050 2.0
float *prt; // pointer member complex a; b ptr=1055
public:
float arg, amp; rl=1.0, img=1.0
complex(float f1=1.0,float f2=1.0) { a ptr= 1050
{ complex b(2.0,3.5); 1055 4.5
rl=f1; img=f2;
ptr = new float(ri+img); // dy alloc from heap a=b;
} }
~complex()
{
delete ptr; // deloc from heap
} return 0;
}
void operator=(const complex &c)
{
rl=f1; img=f2;
ptr = new float(c.ri+c.img); // dy alloc create fresh copy

}; // End of class definition


CS 404; OOPS (Opeartor Overloading) [email protected]
Overloading = (binary) assignment operator
Stack Heap
segment segment
class complex
{ int main(void)
float rl, img, { rl=2.0, img=3.5 1050 2.0
float *prt; // pointer member complex a; b ptr=1055
public:
float arg, amp; rl=2.0, img=3.5
complex(float f1=1.0,float f2=1.0) { a ptr= 1050
{ complex b(2.0,3.5); 1055 4.5
rl=f1; img=f2;
ptr = new float(ri+img); // dy alloc from heap a=b;
} }
~complex()
{
delete ptr; // deloc from heap
} return 0;
}
void operator=(const complex &c)
{
rl=f1; img=f2;
ptr = new float(c.ri+c.img); // dy alloc create fresh copy

}; // End of class definition


CS 404; OOPS (Opeartor Overloading) [email protected]
Overloading = (binary) assignment operator
Stack Heap
segment segment
class complex
{ int main(void)
float rl, img, { rl=2.0, img=3.5 1050 2.0
float *prt; // pointer member complex a; b ptr=1054
public:
float arg, amp; rl=2.0, img=3.5
1054 3.5

complex(float f1=1.0,float f2=1.0) { a ptr= 1050


{ complex b(2.0,3.5); 1055 4.5
rl=f1; img=f2;
ptr = new float(ri+img); // dy alloc from heap a=b;
} }
~complex() Here the operator= function
{
executes the code for deep copying
delete ptr; // deloc from heap
} return 0;
} allocates new (fresh) space for the
void operator=(const complex &c) contents pointed and then copies
{
rl=f1; img=f2; the original pointed data to it
ptr = new float(c.ri+c.img); // dy alloc create fresh copy
return;
}

}; // End of class definition


CS 404; OOPS (Opeartor Overloading) [email protected]
Overloading = (binary) assignment operator
Stack Heap
segment segment
class complex
{ int main(void)
float rl, img, { 1050 2.0
float *prt; // pointer member complex a;
public:
float arg, amp; rl=2.0, img=3.5
1054 3.5

complex(float f1=1.0,float f2=1.0) { a ptr= 1050


{ complex b(2.0,3.5); 1055 4.5
rl=f1; img=f2;
ptr = new float(ri+img); // dy alloc from heap a=b;
} }
~complex() Objects a and b can work
{
independently now onwards
delete ptr; // deloc from heap
} return 0;
} a works well with its own copy of
void operator=(const complex &c) space in heap and works well even
{
rl=f1; img=f2; if b goes out of scope
ptr = new float(c.ri+c.img); // dy alloc create fresh copy

}; // End of class definition


CS 404; OOPS (Opeartor Overloading) [email protected]
Overloading assignment operator =
• Compiler provides a free one if not explicitly overloaded; free one considers shallow copy (bitwise copying)

• If dynamic allocation is used in constructor or the class is having a pointer/reference member overloading = is essential to
implement deep copy

• In other words, if copy constructor needs to be defined overloading = is essential

• Deep copying – allocates new (fresh) space for the contents pointed and then copies the original pointed data to it

• Shallow copying – merely copies the value of the pointer member; hence the new and original pointer continues to point to
the same data; if one modified some of its pointed portion the other gets affected; if one goes out of scope the other
becomes a dangling pointer

• If copy constructor is needed (when the class is having atleast one reference/pointer member) one must overload operator =
explicitly to enable deep copying and vice-versa

CS 404; OOPS (Opeartor Overloading)


[email protected]

You might also like