Computer Science - C++  

LESSON 29:  Classes, Abstraction, operator Overloading (Part II)

INTRODUCTION:            We now continue our development of the time and date class begun in Lesson 28.  This short but important lesson will explain how to overload the built-in input/output operators (>>, <<) for the time and date class. 

The key topics for this lesson are:

  A.      Overloaded I/O Operators

B.      Implementing I/O Operators for the Time Class

C.      Default Assignment Operator

DISCUSSION:      A.      Overloaded I/O Operators

1.      It would be very convenient to use the standard input (>>) and output (<<) stream operators with our time class.  The stream extraction (>>) and insertion (<<) operators have been overloaded in C++ to handle all the built-in types. 

  2.      The stream operators are binary operators - they require two operands.  When we overload the stream operators the left operand will be a stream object, while the right operand will be a time object. 

  3.      Assuming that t1 is a time object, the basic format of an output expression would be:

 

cout << t1;                //  sends t1 to the screen

 

      This is translated as a function call which looks something like:

 

operator<< (cout, t1);

                       

See Handout H.A.28.1. time.h.

      Notice in Handout H.A.28.1, time.h, the prototypes for the two overloaded I/O operators are declared outside the time class.

     

ostream& operator<< (ostream&, const time &); 

        // overloaded << operator

istream& operator>> (istream&, time&);  // overloaded >> operator

 

      Functions which support abilities of a class, but are declared outside of the class are called free functions.

  4.      Because these functions are declared outside of the class, they cannot access the private data members of the time object used as the second parameter.  We need helper functions to help these free functions access private data inside a time object.

  B.      Implementing I/O Operators for the Time Class

  1.      The helper functions consist of overloaded versions of print and getTime.

 

2.      A modified print function has been written which sends the time object to outfile.

 

void time::print(ostream &outfile)  const

{

        if (standard == myDisplay)

                if ((0 == myHour) || (12 == myHour))

                        outfile << "12";

                else

                        printHour (outfile, myHour % 12);

        else

                printHour (outfile, myHour);        // print military hour

        outfile << ":";

        printMinute (outfile, myMinute);        // same for both formats

        if (standard == myDisplay)

                if (myHour < 12) outfile << " am";

                else outfile << " pm";

}

 

      The only difference between this version of print and the first version in Lesson 28 is the flexibility of printing to whatever ostream object is passed to the function.  We are now supporting two overloaded print functions for the time class:

 

      void print () const;

      void print (ostream &) const;

 

3.      We are now ready to implement an overloaded output operator (<<) for a time object.

 

ostream& operator<< (ostream &outfile, const time &temp) 

{

        temp.print (outfile);

        return outfile;

}

 

      The function first calls a different version of the print function; one which receives an ostream parameter.  The output operator function returns outfile to allow for chaining.

 

 

See Handout H.A.29.1, Overloaded Output ()Operator.

4.   See Handout  H.A.29.1 for a more detailed analysis of the sequence of steps involved. 

 

5.      Overloading the input operator (>>) requires a similar approach, using a modified getTime function.

 

istream& operator>> (istream &infile, time &temp) 

{

        temp.getTime(infile);

        return infile;

}

 

void time::getTime(istream &infile)  // to support use of >> operator

{

        int hour, minute;

        char format;

 

        infile >> hour >> minute >> format;

        setTime (hour,minute,format);

}

 

 

C.      Default Assignment Operator

 

1.      The assignment operator (=) can be used with classes and objects which do not involve dynamically allocated memory.  The following type of statements can be used with time objects.

 

time  t1, t2, t3;

 

t1.setTime (5,45,'p');

t3 = t2 = t1;

 

2.      The assignment operator will perform a transfer of all three private data members from one time object to another.

 

3.      If the object involved a pointer to dynamically allocated memory, such as a linked list or binary tree, the assignment operator would need to be explicitly overloaded for that class.  This topic will be covered in a future lesson.

 

 

SUMMARY/REVIEW:            The lab work will continue the development of the date abstraction.

 

ASSIGNMENT:            Lab Exercise, L.A.29.1, Date2