100% found this document useful (1 vote)
72 views29 pages

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
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
100% found this document useful (1 vote)
72 views29 pages

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