Overloading Insertion And Extraction Operators-Introduction To Programming-Lecture Notes, Study notes of Computer Programming

A program is a precise sequence of steps to solve a particular problem. This course includes basic programming structure like loops, operator, memory allocation, reference, pointers etc. It teaches how to be a good programmer. This lecture handout is about: Overloading, Insertion, Extraction, Operators, Stream, Behavior, Cascading, Statement, Executed, Data, Types, Non, members, Library, Class

Typology: Study notes

2011/2012

Uploaded on 08/06/2012

anchal
anchal 🇮🇳

4.6

(9)

95 documents

1 / 10

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
444
Lecture No. 37
Reading Material
Deitel & Deitel - C++ How to Program Chapter 11
11.3, 11.3.1, 11.4, 11.4.1
Summary
x Overloading Insertion and Extraction Operators
x Example 1
x Example 2
x Tips
Overloading Insertion and Extraction Operators
We are already aware that while overloading operators, functions are written and
spirit or behavior of the operators ( +, -, *, / ) is maintained in their implementations.
Similarly the operator’s spirit is kept intact while overloading stream insertion and
extraction operators.
We get an integer as input by writing the following lines:
int i;
cin >> i;
Have a look on the stream extraction operator’s ( >> ) behavior here. The similar
behavior is maintained when we overload this stream extraction operator ( >> ) or
stream insertion operator ( << ).
There are couple of important things to take care of, before starting implementation
for overloading an operator:
The first thing to see is the type of the operator i.e. whether the operator is binary or
unary. The binary operator takes two operands while unary operator takes one. The
number of operands for an operator cannot be changed while overloading it.
Secondly, the programmer has to take care of, what an operator is returning back. For
example, in case of addition ( + ), it returns back the result of addition. So the
cascading statement like a + b + c; can be executed successfully. In this case, at first,
b + c is executed. The result of this operation is returned by the operator +, to add it
in the variable a. So in actual, the operation is carried out as:
docsity.com
pf3
pf4
pf5
pf8
pf9
pfa

Partial preview of the text

Download Overloading Insertion And Extraction Operators-Introduction To Programming-Lecture Notes and more Study notes Computer Programming in PDF only on Docsity!

Lecture No. 37

Reading Material

Deitel & Deitel - C++ How to Program Chapter 11

Summary

 Overloading Insertion and Extraction Operators  Example 1  Example 2  Tips

Overloading Insertion and Extraction Operators

We are already aware that while overloading operators, functions are written and spirit or behavior of the operators ( +, -, *, / ) is maintained in their implementations. Similarly the operator’s spirit is kept intact while overloading stream insertion and extraction operators.

We get an integer as input by writing the following lines: int i; cin >> i; Have a look on the stream extraction operator’s ( >> ) behavior here. The similar behavior is maintained when we overload this stream extraction operator ( >> ) or stream insertion operator ( << ).

There are couple of important things to take care of, before starting implementation for overloading an operator:

The first thing to see is the type of the operator i.e. whether the operator is binary or unary. The binary operator takes two operands while unary operator takes one. The number of operands for an operator cannot be changed while overloading it. Secondly, the programmer has to take care of, what an operator is returning back. For example, in case of addition ( + ), it returns back the result of addition. So the cascading statement like a + b + c; can be executed successfully. In this case, at first, b + c is executed. The result of this operation is returned by the operator + , to add it in the variable a. So in actual, the operation is carried out as:

docsity.com

a + ( b + c).

We want to overload stream extraction ( >> ) and insertion ( << ) operators which are actually already overloaded. See the code lines below:

  1. int i = 123;
  2. double d = 456.12;
  3. float f = 789.1;
  4. cout << i << “ “;
  5. cout << d << “ “;
  6. cout << f;

You can see the lines 5, 6 and 7. The same stream insertion operator ( << ) has been used with different data types of int , double and float. Alternatively, these lines (5, 6 and 7) can be written within statement of one line: cout << i << “ “<< d << “ “<< f;

Similarly, the stream extraction operator ( >> ) is used with different data types in the following manner:

cin >> i; cin >> d; cin >> f;

Here, stream extraction operator is used with different data types of int , double and float. The three lines given above can be written in one cascading line: cin >> i >> d >> f;

The file iostream.h contains the operator overloading declarations for these stream insertion ( << ) and extraction ( >> ) operators for native data types. The declarations inside this file look like the following: istream& operator>>(char); istream& operator>>(unsigned char p) { return operator>>((char)p); } istream& operator>>(signed charp) { return operator>>((char*)p); } istream& operator>>(char& c); istream& operator>>(unsigned char& c) {return operator>>((char&)c);} istream& operator>>(signed char& c) {return operator>>((char&)c);} istream& operator>>(int&); istream& operator>>(long&); #if defined(GNUC) extension istream& operator>>(long long&); extension istream& operator>>(unsigned long long&); #endif istream& operator>>(short&); istream& operator>>(unsigned int&); istream& operator>>(unsigned long&); istream& operator>>(unsigned short&); #if _G_HAVE_BOOL istream& operator>>(bool&);

docsity.com

function returns. Therefore, it does not make sense to return references of the objects, passed by value to the function.

As we are declaring this operator function as friend of our class Vehicle , the private members of Vehicle will be accessible to this operator function. For example, tyre is a private data member of type int inside Vehicle class and inside the operator function’s implementation, we can access it by simply writing v.tyre as:

output << v.tyre;

The above statement actually is: cout << v.tyre; tyre is of native data type int. The output will work for native data types as it is actually cout , which is overloaded for all native data type. We are constructing a building using the basic building blocks. We can use the already used bricks to construct new walls. Similarly, while writing out programs, we implement our overloaded operators using the already available functionality of native data types.

Here is how we overload stream insertion operator ( << ) for our Date class: #include class Date { friend ostream& operator << ( ostream & os, Date d ); // this non-member function is a friend of class date

... ... };

ostream & operator << ( ostream & os, Date d ) { os << d.day << ”.” << d.month << ”.” << d.year; // access private data // as friend return os; };

Likewise, we can overload stream extraction operator ( >> ). All the conditions for overloading this operator are similar to that of stream insertion operator ( >>). It cannot be a member operator, always a non-member operator function, declared as friend of the class to be overloaded for. It returns an object of type istream & , accepts first parameter of type istream &. There is one additional restriction on extraction operator ( >> ) i.e. the second parameter is also passed by reference as that object is modified by this operator function. For our Date class, it is declared as:

istream & operator >> ( istream & input, Date & d );

Note that second parameter can also be passed by reference for insertion operator ( << ) but that is not mandatory and may be used to gain performance. But in case of extraction operator ( >> ), it is mandatory to have second parameter of reference type.

docsity.com

Example 1

Following is our Date class containing the overloaded

insertion ( << ) and extraction ( >> ) operators:

/* Date class containing overloaded insertion and extraction operators. */

include

class Date { public: Date( ) { cout << "\n Parameterless constructor called ..."; month = day = year = 0; }

~Date ( ) { // cout << "\n Destructor called ..."; }

// Methods, not directly related to the example have been taken out from the class

friend ostream & operator << ( ostream & os, Date d ); friend istream & operator >> ( istream & is, Date & d );

private: int month, day, year; };

ostream & operator << ( ostream & os, Date d ) { os << d.day << "." << d.month << "." << d.year; // access private data of //Date being a friend return os; };

istream & operator >> ( istream & is, Date& d ) { cout << "\n\n Enter day of the date: "; cin >> d.day; cout << " Enter month of the date: "; cin >> d.month; cout << " Enter year of the date: "; cin >> d.year;

docsity.com

void getMatrix ( ) ; void displayMatrix ( ) ;

};

Matrix :: Matrix ( int rows = 0 , int cols = 0) { numCols = cols ; numRows = rows ;

for ( int i = 0 ; i < numRows ; i ++ ) { for ( int j = 0 ; j < numCols ; j ++ ) { elements [ i ] [ j ] = 0 ; } } }

void Matrix :: getMatrix ( ) { for ( int i = 0 ; i < numRows ; i ++ ) { for ( int j = 0 ; j < numCols ; j ++ ) { cin >> elements [ i ] [ j ] ; } } }

void Matrix :: displayMatrix ( ) { for ( int i = 0 ; i < numRows ; i ++ ) { cout << "| " ; for ( int j = 0 ; j < numCols ; j ++ ) { cout << elements [ i ] [ j ] << " " ; } cout << "|" << endl ; } }

Matrix matrix (2, 2) ;

matrix.getMatrix ( ) ;

main() docsity.com

matrix.displayMatrix ( ) ;

system ( "PAUSE" ) ;

}

The operator functions ( <<, >> ) are not overloaded for this program. A specific function getMatrix() has been called to get the values for the matrix object this entirely a different way than we used to do for primitive data types. For example, we used to get int i as; cin >> i. Similarly, we called a method displayMatrix() to display the values in the matrix object. We can see here, if we overload insertion ( << ) and extraction ( >> ) operators then the user of our class, does not need to know the specific names of the functions to input and display our objects.

The changed program after overloading insertion, extraction operators and few additional statements to format the output properly: /* Matrix class, with overloaded stream insertion and extraction operators. */ #include #include

class Matrix { float elements[30][30]; int numRows, numCols;

public: Matrix ( int rows = 0 , int cols = 0 ) { numRows = rows; numCols = cols; }

friend ostream & operator << ( ostream & , Matrix & ); friend istream & operator >> ( istream & , Matrix & ); };

istream & operator >> ( istream & input , Matrix & m ) { for ( int i = 0; i < m.numRows; i ++ ) { for ( int j = 0; j < m.numCols; j ++ ) { input >> m.elements [ i ] [ j ] ; } } return input; }

docsity.com

to pass the second parameter (the Matrix object in this case) by reference but we have used here to gain efficiency. The function is returning an object ostream & , i.e., it is returning a reference to a ostream object, that actually is the required in order to support cascaded operations using this operator. The extraction operator ( >> ) is also accepting both the parameters by reference. But for this operator, it is mandatory to accept the Matrix object by reference because this function is modifying that object. Similar to the insertion operation, this function is also returning a reference to istream object in order to support cascaded operations. Clearly after overloading the operators << and >>, it is more convenient for the programmer to use these already familiar operators to display and input the object data members. Readability of the program has also comparatively increased.

Tips

 Stream insertion ( << ) and extraction operators ( >> ) are always implemented as non-member functions.

 operator << returns a value of type ostream & and operator

>> returns a value of type istream & to support cascaded operations.

 The first parameter to operator << is an ostream & object.

cout is an example of an ostream object. Similarly first parameter to operator >> is an istream & object. cin is an example of an istream object. These first parameters are always passed by reference. The compiler won't allow you to do otherwise.

 For operator >>, the second parameter must also be

passed by reference.  The second parameter to operator << is an object of the class that we are overloading the operator for. Similar is the case for operator >>.

docsity.com