Computer Science - C++ LESSON 27:  enumerations, operator overloading

 

INTRODUCTION:            Extending the abilities of a programming language is a desirable goal.  The built-in scalar types of integer, double, char, and bool are limited in their ability to represent other types of data.  In this lesson, you will examine the C++ tool to create enumerations, a user-defined type.

The output operator (<<) is already overloaded to work with standard scalar values.  After creating an enumeration, you will learn how to overload operators to work with enumerations.

The key topics for this lesson are:

  A.      Enumerations

B.      Operator Overloading - Overloading the Output Operator (<<)

C.      Overloading the Input Operator (>>)

  VOCABULARY:            ENUMERATIONS            OPERATOR OVERLOADING

  DISCUSSION:      A.      Enumerations 

1.      There are programming situations where the predefined data types do not adequately describe a new data type.  For example in the world of physics there exists the color spectrum ROYGBIV.  The colors red, orange, yellow, green, blue, indigo, and violet could be represented with integers or characters, but it would be more descriptive to use the actual words.

2.      C++ provides for enumerated types.  An enumeration consists of two parts:  a name for the new type, and a list of all the values of this new type.  For example:

      enum  color  {red, orange, yellow, green, blue, indigo, violet};

              // notice the ; at the end of the line

      When color is compiled the value red is mapped as an integer value 0 and violet is mapped as integer value 6.  This process of object-to-integer mapping is taken care of by the compiler.

3.      We can then declare variables of this new type called color.

      color  tint1, tint2;

      tint1 = yellow;

      tint2 = tint1;

4.      The following program uses an enumeration for the days of the week.

Program 27-1

#include <iostream.h>

enum day  {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Badday}; // don't forget the ;

main ()

{

        day  day1 = Friday;

        day  day2;

        cout << "day1 = " << day1;

        cout << "day2 = " << day2;

        return 0;

}

 

Run output:

day1 = 5;

day2 = 1520;   (machine-dependent)

5.      The output of program 27-1 is an integer.  Notice that day2 has an uninitialized garbage integer value. 

6.      An error value called Badday was added to facilitate error-checking.  If an invalid day is input we can process this error using the value Badday.

  7.      It would be very convenient if we could write code like,

      cout << day1;

      and have the output on the screen be the value Friday.  We now overload the output operator (<<) to work with enumerations.

  B.      Operator Overloading - Overloading the Output Operator (<<)

  1.      An overloaded operator is one which performs a different function depending on its context.  For example, in C++, the addition operator (+) has been overloaded to add integers or doubles.

  2.      Overloaded operators are created using function definitions.  Four steps are required to overload an operator:

a.            Name the operator being overloaded.

b.            Specify the operands the operator is to receive.  This will be solved using parameters to a function.

c.            Specify the type of value returned by the operator.

d.            Specify what action the operator is to perform.

       The sequential development of an overloaded output (<<) operator to support the statement    cout << day1   follows.

3.      The reserved word operator allows the C++ programmer to overload an operator.  We wish to overload the output operator so we begin with:

      operator<<

4.      The operation   cout << day1  can be thought of as the call,  operator<< (cout, day1).  We now specify the operands of our overloaded operator:

      operator<< (ostream &Out, day someDay)

      The ostream value Out is set up as a reference parameter.  The ostream &Out will be an alias for whatever ostream is sent in the calling statement.

5.      We would like our overloaded output operator to support chaining.  Recall that the output operator is left-associative which means that the statement,  cout << day1 << endl; is solved in this order:

      (((cout << day1) << endl);

      The result of (cout << day1) is cout, the name of the output stream.  The << operator must return the ostream object which it received as its parameter.  We now add the return type to our overloaded operator:

      ostream& operator<< (ostream &Out, day someDay)

6.      Finally, we specify the action of the overloaded operator.  In this case we want the function to print the corresponding string for a variable of type day.

      ostream& operator<< (ostream &Out, day someDay)

{

switch (someDay)

{

      case Sunday:  Out << "Sunday";  break;

      case Monday:  Out << "Monday"; break;

      case Tuesday:  Out << "Tuesday"; break;

      case Wednesday:  Out << "Wednesday"; break;

      case Thursday:  Out << "Thursday"; break;

      case  Friday:  Out << "Friday"; break;

      case  Saturday:  Out << "Saturday"; break;

      case  Badday:  Out << "Invalid day"; break;

}

return Out;

      }

7.      We can now use this overloaded operator with our new enumerated variable type.

Program 27-2

 

#include <iostream.h>

 

enum day  {Sunday, Monday, Tuesday, Wednesday, Thursday,

                        Friday, Saturday, Badday};        // don't forget the ;

 

main ()

{

        day  day1 = Monday;

        day  day2 = Friday, day3;

 

        cout << "day1 = " << day1 << "   day2 = " << day2 << endl;

        day3 = day2;

        cout << "day3 = " << day3 << endl;

        return 0;

}

 

Run output:

 

day1 = Monday   day2 = Friday

day3 = Friday

 

 

C.      Overloading the Input Operator (>>)

 

1.      Overloading the input operator for the enumeration of day is a similar process to overloading the output operator.  However we will need to consider the nature of the input.

 

2.      We would like to support statements such as:

 

      cin >> day1

 

3.      The nature of the input is a string.  The expected input of

     

      cin >> day1

 

      would be a string such as Monday, Friday, etc.

 

4.      The function we write to overload the input operator will need to deal with string input.  We should also allow the user to input the day of the week in any combination of upper or lowercase letters.  As long as the day is spelled correctly the input operation should be successful.

 


5.      Here is an overloaded input operator function to work with variables of type day:

 

istream& operator>> (istream &In, day &someDay)

{

        apstring  tempDay;

 

        In >> tempDay;

        for (int pos=0; pos<tempDay.length(); pos++)

                if (('A'<=tempDay[pos]) && (tempDay[pos]<='Z'))

                        tempDay[pos] = tempDay[pos] + 32;  // make it all lowercase

        if (tempDay == "sunday") someDay = Sunday;

        else if (tempDay == "monday") someDay = Monday;

        else if (tempDay == "tuesday") someDay = Tuesday;

        else if (tempDay == "wednesday") someDay = Wednesday;

        else if (tempDay == "thursday") someDay = Thursday;

        else if (tempDay == "friday") someDay = Friday;

        else if (tempDay == "saturday") someDay = Saturday;

        else someDay = Badday;

        return In;

}

 

6.      A local string, tempDay, is used to get data from the istream In.  The string is converted to all lowercase letters to allow for clean comparisons with possible day values.  The appropriate value is returned as someDay.  Notice the return type of the function, the istream In.  This allows for chaining of input statements such as:

 

      cin >> day1 >> day2;

 

 

SUMMARY/REVIEW:            Enumerations provide a convenient method for working with real-world values.  The ability to overload operators in C++ will be extended in the next lessons on classes.

ASSIGNMENT:            Lab Exercise, L.A.27.1, Cards