18
1 Electronic Science C and C++ Programming 33. Operator Overloading and Type Conversion Module - 33 Operator Overloading and Type Conversion Table of Contents 1. Introduction 2. Operator Overloading 3. this pointer 4. Overloading Unary Operators 5. Overloading Binary Operators 6. Overloading Insertion and Extraction Operators 7. Manipulation of Strings using Operators 8. Rules for Overloading operators 9. Type Conversions 10. Summary Learning outcome After studying this module, you will be able to: 1. Understand about Operator Overloading 2. Study about this pointer 3. Learn about Overloading Unary Operators 4. Learn about Overloading Binary Operators 5. Get familiar with Overloading Insertion and Extraction operators 6. Study about manipulation of strings using operators 7. Get familiar with Rules for overloading operators 8. Study about Type Conversions

Module - 33 Operator Overloading and Type Conversion Table

  • Upload
    others

  • View
    10

  • Download
    0

Embed Size (px)

Citation preview

1

Electronic Science C and C++ Programming

33. Operator Overloading and Type Conversion

Module - 33

Operator Overloading and Type Conversion

Table of Contents

1. Introduction

2. Operator Overloading

3. this pointer

4. Overloading Unary Operators

5. Overloading Binary Operators

6. Overloading Insertion and Extraction Operators

7. Manipulation of Strings using Operators

8. Rules for Overloading operators

9. Type Conversions

10. Summary

Learning outcome –

After studying this module, you will be able to:

1. Understand about Operator Overloading

2. Study about this pointer

3. Learn about Overloading Unary Operators

4. Learn about Overloading Binary Operators

5. Get familiar with Overloading Insertion and Extraction operators

6. Study about manipulation of strings using operators

7. Get familiar with Rules for overloading operators

8. Study about Type Conversions

2

Electronic Science C and C++ Programming

33. Operator Overloading and Type Conversion

1. Introduction

The Operator overloading is one of the important feature of C++. It is a type of polymorphism in

which an operator is overloaded to give user defined meaning to it. The operator that is

overloaded is used to perform operation on user-defined data type. C++ permits to add two

variables of user-defined types with the same syntax that was applied to the basic types.

2. Operator Overloading

C++ has ability to provide the operators with a unique meaning for a data type. The mechanism

of giving unique meaning to an operator is known as operator overloading. The Operator overloading offers a flexible option for the creation of new definitions for most of the C++ operators. Even though the semantics of an operator can be extended, but, it is not possible to

modify its syntax and the grammatical rules that manage its use such as number of operands, precedence and associativity. The Operator overloading can be done by implementing a function

which can be Member Function or a Friend Function. The two types of operator overloading that are supported by C++ are Unary operator overloading and Binary operator overloading. The Operator overloading can be done with the help of a special function, called “operator” function.

Syntax: return_type classname :: operator op(arglist)

{ function body // task defined }

In the above syntax:

The return-type is the type of value returned by the specified operation and op is the operator being overloaded.

The op is preceded by the keyword operator, where operator op is function name.

The Operator function must be either member functions (non-static) or friend function. The

basic difference between them is that a friend function will have only one argument for unary operators and two for binary operators, while a member function has no arguments for unary

operators and only one for binary operators. This is because the object used to invoke the member function is passed implicitly and therefore it is available for the member function, where as it is not the case with friend functions. The Arguments may be passed either by value or by

reference.

2.1 Steps of overloading

The steps that are to be followed in process of overloading are: i) Create a class that defines the data type that is to be used in the overloading operation.

ii) Declare the operator function operator op() in the public part of the class. It may be either a member function or friend function.

iii) Define the operator function to implement the required operations. 2.2 Operators that can be overloaded

The operators which can be overloaded are:

3

Electronic Science C and C++ Programming

33. Operator Overloading and Type Conversion

2.3 Operators that cannot be overloaded

The operators that cannot be overloaded are: Class member access operators ( . & .*)

Scope resolution operator ( : : ) Size of operator (sizeof)

Conditional operator (? : )

The operators that cannot be overloaded using friend function are ‘=‘, ‘->’, ‘[]’ and ‘()’

4. Overloading Unary Operators

The overloading of unary operators can be performed using:

Member function

Friend function

4.1 Overloading Unary Operators using Member function

In case of unary operator, since it operates on only one operand, the operand itself calls the overloaded operator function. Therefore, the argument is not sent to the function.

Syntax: return_type operator op() {

// function code }

Example: demo operator –()

{ demo temp;

temp.num = -num; return temp; }

Program to implement the usage of unary minus operator

#include<iostream>

Operators that can be overloaded

+ - * / % ^ & |

~ ! = < > += -= *=

/= %= ^= &= |= << >> >>=

<<= == != <= >= && || ++

-- ->* , -> [] () new delete

new[] delete[]

4

Electronic Science C and C++ Programming

33. Operator Overloading and Type Conversion

using namespace std;

class Minus {

private: int a, b, c ;

public: Minus(int A, int B, int C) {

a = A; b = B;

c = C; } void display(void);

void operator - ( ); };

void Minus :: display(void) { cout << "\t a = " << a << endl ;

cout << "\t b = " << b << endl ; cout << "\t c = " << c << endl ;

} void Minus :: operator - ( ) {

a = -a ; b = -b ;

c = -c ; } int main()

{ Minus M(5, 10, -15) ;

cout << "\n Before activating operator - ( )\n" ; M.display( ) ; -M ;

cout << "\n After activating operator - ( )\n" ; M.display( ) ;

}

When the above code is compiled and executed, it produces the fo llowing result:

Before activating operator - ( ) a = 5

b = 10 c = -15

After activating operator - ( ) a = -5

5

Electronic Science C and C++ Programming

33. Operator Overloading and Type Conversion

b = -10 c = 15

Program to illustrate the usage of ++ operator overloading #include <iostream>

using namespace std;

class temp

{

private:

int count;

public:

temp():count(5)

{

}

void operator ++()

{

count=count+1;

}

void Display()

{

cout<<"Count: "<<count;

}

};

int main()

{

temp t;

++t;

t.Display();

return 0;

}

When the above code is compiled and executed, it produces the following result: Count : 6

4.2 Overloading Unary Operators using friend function

When unary operator is overloaded using a friend function, it is must to pass one argument to the friend function, because friend function does not have, ‘this’ pointer. If an attempt is made to

modify some value of an object which is passed as argument, then the friend function actually only operates on a copy, because it is passed by value. Thus it is must to work on a copy of the

object, so that it returns a newly initialized object having the modified values. To work directly on the original object, the reference parameters can be used in the operator overloaded frie nd function.

Program to overload increment operator using friend function

6

Electronic Science C and C++ Programming

33. Operator Overloading and Type Conversion

#include<iostream> using namespace std;

class point

{ private:

int x,y; public: point(int i,int j)

{ x=i;

y=j; } void show()

{ cout<<"point="<<"("<<x<<","<<y<<")"<<endl;

} friend void operator++(point &p1); };

void operator++(point &p1) {

p1.x++; p1.y++; }

int main() {

point p1(2,2); p1.show(); cout<<"after increment"<<endl;

++p1; p1.show();

return 0; } When the above code is compiled and executed, it produces the following result:

point=(2,2) after increment

point=(3,3) 5. Overloading Binary Operators

The binary operator overloading can be performed using:

Member function

Friend function

5.1 Overloading Binary Operators using Member function

When overloading binary operator using operator function as class member function, the left side

operand must be an object of the class and right side operand may be either a built- in type or user

7

Electronic Science C and C++ Programming

33. Operator Overloading and Type Conversion

defined type. It is possible to have the consecutive overloading of the binary operators. The

binary operators overloaded through member function takes one argument which is formal. The

binary overloaded operator function takes the first object as an implicit operand and the second

operand must be passed explicitly. The Function Prototype which is to be included when

overloading binary operator using member function of the class should be as follows:

returnType operator op(const className&) const;

The Function Definition should be as follows: returnType className::operator op (const className& otherObject) const

{ //algorithm to perform the operation return (value);

}

Program to implement the usage of binary operator overloading using member function

#include<iostream>

using namespace std;

class complex

{

int a,b;

public:

void getvalue()

{

cout<<"Enter the value of Complex Numbers a,b:";

cin>>a>>b;

}

complex operator+(complex c)

{

complex t;

t.a=a+c.a;

t.b=b+c.b;

return(t);

}

complex operator-(complex c)

{

complex t;

t.a=a-c.a;

t.b=b-c.b;

return(t);

8

Electronic Science C and C++ Programming

33. Operator Overloading and Type Conversion

}

void display()

{

cout<<a<<"+"<<b<<"i"<<"\n";

}

};

int main()

{

complex c1,c2,c3,c4;

c1.getvalue();

c2.getvalue();

c3 = c1+c2;

c4=c1-c2;

cout<<"Complex number1:\n";

c1.display();

cout<<"Complex number2:\n";

c2.display();

cout<<"sum =";

c3.display();

cout<<"\ndifference =";

c4.display();

return 0;

}

When the above code is compiled and executed, it produces the following result:

Enter the value of Complex Numbers a,b: 1 3

Enter the value of Complex Numbers a,b: -2 4

Complex number1:

1+3i

Complex number2:

-2+4i

sum =-1+7i

difference =3+-1i

Program to overload relational operators

#include <iostream>

using namespace std;

class Distance

{

private:

9

Electronic Science C and C++ Programming

33. Operator Overloading and Type Conversion

int feet;

int inches;

public:

Distance()

{

feet = 0;

inches = 0;

}

Distance(int f, int i)

{

feet = f;

inches = i;

}

void displayDistance()

{

cout << "F: " << feet << " I:" << inches <<endl;

}

Distance operator- ()

{

feet = - feet;

inches = - inches;

return Distance(feet, inches);

}

bool operator <(const Distance& d)

{

if(feet < d.feet)

{

return true;

}

if(feet == d.feet && inches < d.inches)

{

return true;

}

return false;

}

};

int main()

{

Distance D1(11, 10), D2(5, 11);

if( D1 < D2 )

10

Electronic Science C and C++ Programming

33. Operator Overloading and Type Conversion

{

cout << "D1 is less than D2 " << endl;

}

else

{

cout << "D2 is less than D1 " << endl;

}

return 0;

}

When the above code is compiled and executed, it produces the following result:

D2 is less than D1

5.2 Overloading Binary Operator using friend Functions

The private members of the class cannot be accessed through outside functions, but, it is possible

by using friend functions. Friend functions may be used in place of member functions for

overloading a binary operator. The difference is that friend function requires two arguments to be

explicitly passed to it while a member function requires only one argument. The Function

Prototype which is to be included when overloading binary operator using friend function of the

class should be as follows:

friend returnType operator op(const className&, const className&);

The Function Definition should be as follows:

returnType operator op(const className& firstObject, const className& secondObject)

{

//code to perform the operation

return (value);

}

Program to implement the usage of binary operator overloading using friend function

#include <iostream>

using namespace std;

class myclass

{

int a;

int b;

public:

myclass(){}

myclass(int x,int y)

{

a=x;

b=y;

11

Electronic Science C and C++ Programming

33. Operator Overloading and Type Conversion

}

void show()

{

cout<<a<<endl<<b<<endl;

}

friend myclass operator+(myclass,myclass);

friend myclass operator-(myclass,myclass);

};

myclass operator+(myclass ob1,myclass ob2)

{

myclass temp;

temp.a = ob1.a + ob2.a;

temp.b = ob1.b + ob2.b;

return temp;

}

myclass operator-(myclass ob1,myclass ob2)

{

myclass temp;

temp.a = ob1.a - ob2.a;

temp.b = ob1.b - ob2.b;

return temp;

}

int main()

{

myclass a(100,200);

myclass b(10,20),c,d;

c=a+b;

c.show();

d = a-b;

d.show();

return 0;

}

When the above code is compiled and executed, it produces the following result:

110

220

90

180

6. Overloading Insertion and Extraction operators

12

Electronic Science C and C++ Programming

33. Operator Overloading and Type Conversion

C++ is able to input and output the built- in data types using the stream insertion operator (<<)

and extraction operator (>>). The stream insertion and stream extraction operators also can be

overloaded to perform input and output for user-defined types like an object. It is important to

make operator overloading function a friend of the class because it would be called without

creating an object.

Program to overload stream insertion and stream extraction operators

#include <iostream>

using namespace std;

class Distance

{

private:

int feet;

int inches;

public:

Distance()

{

feet = 0;

inches = 0;

}

Distance(int f, int i)

{

feet = f;

inches = i;

}

friend ostream &operator<<( ostream &output, const Distance &D )

{

output << "F : " << D.feet << " I : " << D.inches;

return output;

}

friend istream &operator>>( istream &input, Distance &D )

{

input >> D.feet >> D.inches;

return input;

}

};

int main()

{

Distance D1(11, 10), D2(5, 11), D3;

cout << "Enter the value of object : " << endl;

13

Electronic Science C and C++ Programming

33. Operator Overloading and Type Conversion

cin >> D3;

cout << "First Distance : " << D1 << endl;

cout << "Second Distance :" << D2 << endl;

cout << "Third Distance :" << D3 << endl;

return 0;

}

When the above code is compiled and executed, it produces the following result:

Enter the value of object :

70

10

First Distance : F : 11 I : 10

Second Distance :F : 5 I : 11

Third Distance :F : 70 I : 10

7. Manipulation of Strings using Operators

The ANSI C language implements the strings with the help of character arrays, pointers and

string functions. It does not provide operators for manipulation of strings. For example, to copy a

string, it is must that, initially, the length of the string is to be found, then it has to allocate

required amount of memory. Even in C++ language, these problems arises, but in C++ language,

it is possible to create own definitions of the operators that can be used to modify the strings in

the same way like that of decimal numbers. It is possible by a new class called as string class

which helps to overload a small number of operators to work on string objects, some of them are:

String comparison (==, !=, >, <, >=, <=)

Example:

The statement str1 == str2 can be used to compare the contents of two string objects.

Stream insertion and extraction (<<, >>)

Example:

cout << str1 and cin >> str2 can be used to output/input string objects.

Assignment (=)

Example:

str1 = str2 assigns str2 into str1.

Strings concatenation (+, +=)

Example:

str1 + str2 concatenate two string objects to produce a new string object.

str1 += str2 appends str2 intostr1.

14

Electronic Science C and C++ Programming

33. Operator Overloading and Type Conversion

Character indexing or subscripting []

The [] operator does not perform index-bound check, i.e., it is must to ensure that the

index is within the bounds. To perform index-bound check, the string's at() member

function can be used.

Example:

str[n] can be used to get the char at index n;

str[n] = c can be used to modify the char at index n.

8. Restrictions on Overloaded Operators

The restrictions on overloaded operators are: Operators can be overloaded only for user defined types or a mix of user defined types

and fundamental types.

Only the operators which are part of C++ language can be overloaded. No new operator can be created using operator overloading.

The number of operands that an operator takes (arity) cannot be changed. Any overloaded operator function must have at least one operand which is user-defined

type. All of the operands cannot be of basic types. If this is the case, then function must

be friend function of some class. The meaning of the operator i.e. “+” can be overloaded to perform multiplication

operation or “>” operator can be overloaded to perform addition operation, but their priority of the operator cannot be changed.

The operator precedence cannot be changed in overloading.

The operator associativity (left to right or right to left) cannot be changed in overloading. In case of overloading binary operators, left hand side operator must be an object of class

when overloaded operator function is a member function of the class. Binary operators overloaded through member function of the class take one argument and

overloaded through friend function take two arguments.

Unary operators overloaded through member function of the class does not take any argument and overloaded through friend function must take one argument.

9. Type Conversions

In many situations, it is required to convert one data type into another. The process of converting data type of a variable into other data type is known as type conversion. When conversion of int to float, char to int, double to int etc. is done, compiler also does implicit type conversion. In

general, type conversion with respect to user data type, i.e., class is divided into 3 parts, they are as follows:

i) Conversion from built-in types to class type.

To convert basic built- in type into class types, the simple method is to define parameterized

constructor which takes an argument of basic type which is to be converted to class type. The

15

Electronic Science C and C++ Programming

33. Operator Overloading and Type Conversion

constructors perform actual type conversion from the argument’s type to the constructor’s class type.

a) Conversion of int to class type

Define a one argument constructor type int as follows:

demo (int) {

constructor body; } Example:

In the main(), the statement is written as demo d=10; When compiler find this statement, it come to know that both types demo and int are not compatible so it look for conversion routine which

can convert an int into demo class type. When it finds there is a constructor which takes int as argument, it calls constructor, pass the int value 10 and construct the object and assign to d.

b) Conversion of char* to class type

Suppose if the code is as follows:

string (char *a) { length=strlen(a);

p= new char[length+1]; strcpy(p, a);

} It builds a string type object from a char* type variable a. The variable length and p are data members of the class string. Once constructor is defined and it is used for conversion from char *

type to string type.

ii) Conversion from class type to built-in types

To convert class type to built- in type, the method that is to be adopted is that simple i.e., define an operator function by the name of data type the class data type to be converted to.

The general form is as follows: operator data_type()

{ } In the above syntax, the operator is the keyword and data-type is the type in which the class type

will be converted to. There is no return type or argument specified for the function. It is a member of class so any data

member or function can be used inside this conversion function. Any processing over data member can be done as per requirement, but in the end, as function is about to return, it is must to return a value of type data_type.

Example:

Conversion of Class Type to int

Suppose if the code is as follows: operator int()

{

16

Electronic Science C and C++ Programming

33. Operator Overloading and Type Conversion

int x; computing steps;

return x; } In the main(), it is written int num=d; where d is an object of demo class type. When Compiler

finds the statement, int num =d; it comes to know that both types are not compatible so it look for conversion routine that converts an object of class to int.

The casting operator function must satisfy the following conditions and they are as follows:

It must be a class member

It must not specify a return type

It must not have any arguments.

Since it is a member function, it is invoked by the object and, hence the values used for conversion inside the function belong to the object invoking the function. It means the

function does not need an argument.

iii) Conversion from one class type to another

Example Suppose if the code is as follows:

objx = objy; In the above code, the objx is an object of class X and objy is an object of class Y. The class Y type data is converted to the class X type data and the converted value is assigned to the objX.

Since the conversion takes place from class Y to class X, Y is known as the source class and X is known as the destination class. Such conversions between objects of different classes can be

carried out by either a constructor or a conversion function. The casting operator function should be as follows: operator typename()

The above function converts the class object of which it is a member to typename. The typename may be a built- in type or a userdefined one (another class type).

In case of conversion between objects, typename refers to the destination class. When class needs to be converted, a casting operator function can be used (i.e. source class). The conversion takes place in the source class and the result is given to the destination class object. In case of a

single-argument, constructor function serves as an instruction for converting the argument’s type to the class type of which it is member. It implies that the arrangement belongs to the source

class and is passed to the destination class for conversion. It should be remembered that it is necessary that the conversion constructor be placed in the destination class. When a conversion using a constructor is performed in the destination class, it must able to access the data members

of the object sent (by source class) as an argument, since data members of the source class are private, it is must to use special access functions in the source class to facilitate its data flow to

the destination class. Type conversion from one class to another class can be represented in the figure as follows:

17

Electronic Science C and C++ Programming

33. Operator Overloading and Type Conversion

Type conversion from one class to another class can be represented in the table as follows:

10. Summary

C++ has ability to provide the operators with a unique meaning for a data type.

The mechanism of giving unique meaning to an operator is known as operator

overloading.

The Operator overloading can be done by implementing a function which can be Member

Function or a Friend Function.

The two types of operator overloading that are supported by C++ Unary operator

overloading and Binary operator overloading.

The Operator overloading can be done with the help of a special function, called “operator” function.

The basic difference between them is that a friend function will have only one argument

for unary operators and two for binary operators, while a member function has no

arguments for unary operators and only one for binary operators.

The operators that cannot be overloaded are Class member access operators ( . & .*),

Scope resolution operator ( : : ), Size of operator (sizeof), Conditional operator (? : )

The operators that cannot be overloaded using friend function are ‘=‘, ‘->’, ‘[]’ and ‘()’

Every object in C++ has access to its own address through an important pointer

called this pointer.

“this” pointer is an implicit parameter to all member functions, therefore, inside a

member function, it may be used to refer to the invoking object.

18

Electronic Science C and C++ Programming

33. Operator Overloading and Type Conversion

“this” pointer is not available in static member functions as static member functions can

be called without any object.

In case of unary operator, since it operates on only one operand, the operand itself calls

the overloaded operator function.

When unary operator is overloaded using a friend function, it is must to pass one

argument to the friend function, because friend function does not have, ‘this’ pointer.

To work directly on the original object, the reference parameters can be used in the

operator overloaded friend function.

When overloading binary operator using operator function as class member function, the

left side operand must be an object of the class and right side operand may be either a

built- in type or user defined type.

The binary overloaded operator function takes the first object as an implicit operand and

the second operand must be passed explicitly.

The private members of the class cannot be accessed through outside functions, but, it is

possible by using friend functions.

The difference is that friend function requires two arguments to be explicitly passed to it

while a member function requires only one argument.

The stream insertion and stream extraction operators also can be overloaded to perform

input and output for user-defined types like an object.

It is possible by a new class called as string class which helps to overload a small number

of operators to work on string objects.

The [] operator does not perform index-bound check, i.e., it is must to ensure that the

index is within the bounds.

Only the operators which are part of C++ language can be overloaded. No new operator can be created using operator overloading.

The operator precedence cannot be changed in overloading.

The process of converting data type of a variable into other data type is known as type

conversion.

To convert basic built- in type into class types, the simple method is to define

parameterized constructor which takes an argument of basic type which is to be

converted to class type.

To convert class type to built- in type, the method that is to be adopted is that simple i.e.,

define an operator function by the name of data type the class data type to be converted to.

When a conversion using a constructor is performed in the destination class, it must able to access the data members of the object sent (by source class) as an argument, since data members of the source class are private, it is must to use special access functions in the

source class to facilitate its data flow to the destination class.