classes: a deeper look, part 1 - deekle.netdeekle.net/jones/fallandwinter2005-6/cop/09.pdf9 classes:...

50
9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor wrapper to prevent multiple definition errors caused by including more than one copy of a header file in a source-code file. To understand class scope and accessing class members via the name of an object, a reference to an object or a pointer to an object. To define constructors with default arguments. How destructors are used to perform “termination housekeeping” on an object before it is destroyed. When constructors and destructors are called. The logic errors that may occur when a public member function of a class returns a reference to private data. To assign the data members of one object to those of another object by default memberwise assignment. My object all sublime I shall achieve in time. —W. S. Gilbert Is it a world to hide virtues in? —William Shakespeare Don’t be “consistent,” but be simply true. —Oliver Wendell Holmes, Jr. This above all: to thine own self be true. —William Shakespeare

Upload: others

Post on 08-Mar-2021

4 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

9Classes: A Deeper Look, Part 1

O B J E C T I V E SIn this chapter you will learn:

■ How to use a preprocessor wrapper to prevent multiple definition errors caused by including more than one copy of a header file in a source-code file.

■ To understand class scope and accessing class members via the name of an object, a reference to an object or a pointer to an object.

■ To define constructors with default arguments.

■ How destructors are used to perform “termination housekeeping” on an object before it is destroyed.

■ When constructors and destructors are called.

■ The logic errors that may occur when a public member function of a class returns a reference to private data.

■ To assign the data members of one object to those of another object by default memberwise assignment.

My object all sublimeI shall achieve in time.—W. S. Gilbert

Is it a world to hide virtues in?—William Shakespeare

Don’t be “consistent,” but be simply true.—Oliver Wendell Holmes, Jr.

This above all: to thine own self be true.—William Shakespeare

cpphtp5_09_IM.fm Page 480 Thursday, December 23, 2004 4:14 PM

Page 2: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 481

Self-Review Exercises9.1 Fill in the blanks in each of the following:

a) Class members are accessed via the operator in conjunction with the nameof an object (or reference to an object) of the class or via the operator inconjunction with a pointer to an object of the class.

ANS: dot (.), arrow (->).b) Class members specified as are accessible only to member functions of the

class and friends of the class.ANS: private.c) Class members specified as are accessible anywhere an object of the class is

in scope.ANS: public. d) can be used to assign an object of a class to another object of the same class.ANS: Default memberwise assignment (performed by the assignment operator).

9.2 Find the error(s) in each of the following and explain how to correct it (them): a) Assume the following prototype is declared in class Time:

void ~Time( int );

ANS: Error: Destructors are not allowed to return values (or even specify a return type) ortake arguments.Correction: Remove the return type void and the parameter int from the declara-tion.

b) The following is a partial definition of class Time:

class Time{public: // function prototypes

private: int hour = 0; int minute = 0; int second = 0;}; // end class Time

ANS: Error: Members cannot be explicitly initialized in the class definition. Correction: Remove the explicit initialization from the class definition and initializethe data members in a constructor.

c) Assume the following prototype is declared in class Employee:

int Employee( const char *, const char * );

ANS: Error: Constructors are not allowed to return values.Correction: Remove the return type int from the declaration.

Solutions9.3 What is the purpose of the scope resolution operator?

ANS: The scope resolution operator is used to specify the class to which a function belongs.It also resolves the ambiguity caused by multiple classes having member functions ofthe same name. It also associates a member function in a .cpp file with a class defini-tion in a .h file.

cpphtp5_09_IM.fm Page 481 Thursday, December 23, 2004 4:14 PM

Page 3: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

482 Chapter 9 Classes: A Deeper Look, Part 1

9.4 (Enhancing Class Time) Provide a constructor that is capable of using the current time fromthe time() function—declared in the C++ Standard Library header <ctime>—to initialize an objectof the Time class.

ANS: [Note: We provide two solutions. The first one only uses function time. The secondone uses several other data member and functions in <ctime> header.]

1 // Exercise 9.4 Solution: Time.h2 #ifndef TIME_H3 #define TIME_H4 5 class Time 6 {7 public:8 Time(); // constructor9 void setTime( int, int, int ); // set hour, minute and second

10 void printUniversal(); // print time in universal-time format11 void printStandard(); // print time in standard-time format12 private:13 int hour; // 0 - 23 (24-hour clock format)14 int minute; // 0 - 5915 int second; // 0 - 5916 bool isLeapYear( int ); // check if input is a leap year17 }; // end class Time1819 #endif

1 // Exercise 9.4 Solution: Time.cpp2 // Member-function definitions for class Time.3 #include <iostream> 4 using std::cout;56 #include <iomanip>7 using std::setfill;8 using std::setw;9

10 #include <ctime>11 using std::time;1213 #include "Time.h" // include definition of class Time from Time.h1415 Time::Time()16 {17 const int CURRENT_YEAR = 2004;18 const int START_YEAR = 1970;19 const int HOURS_IN_A_DAY = 24;20 const int MINUTES_IN_AN_HOUR = 60;21 const int SECONDS_IN_A_MINUTE = 60;22 const int DAYS_IN_A_YEAR = 365;23 const int DAYS_IN_A_LEAPYEAR = 366;24 const int TIMEZONE_DIFFERENCE = 5;25 int leapYear = 0;26 int days;27

cpphtp5_09_IM.fm Page 482 Thursday, December 23, 2004 4:14 PM

Page 4: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 483

28 // calculate leap year29 for ( int y = START_YEAR; y <= CURRENT_YEAR; y++ )30 {31 if ( isLeapYear( y ) )32 leapYear++;33 } // end for3435 int dayTimeInSeconds = time( 0 ) - HOURS_IN_A_DAY * 36 MINUTES_IN_AN_HOUR * SECONDS_IN_A_MINUTE * ( 37 DAYS_IN_A_YEAR * ( CURRENT_YEAR - START_YEAR ) + leapYear );3839 // calculate current second, minute and hour40 for ( int s = 0; s < SECONDS_IN_A_MINUTE; s++ )41 {42 for ( int m = 0; m < MINUTES_IN_AN_HOUR; m++ )43 {44 for ( int h = 0; h <= HOURS_IN_A_DAY; h++ )45 {46 if ( isLeapYear( CURRENT_YEAR ) )47 days = DAYS_IN_A_LEAPYEAR;48 else49 days = DAYS_IN_A_YEAR;5051 for ( int d = 0; d <= days; d++ )52 {53 if ( s + m * SECONDS_IN_A_MINUTE + 54 h * MINUTES_IN_AN_HOUR * SECONDS_IN_A_MINUTE + 55 d * HOURS_IN_A_DAY * MINUTES_IN_AN_HOUR * 56 SECONDS_IN_A_MINUTE == dayTimeInSeconds )57 {58 setTime( h-TIMEZONE_DIFFERENCE, m, s );59 } // end if60 } // end for61 } // end for62 } // end for63 } // end for64 } // end Time constructor6566 // set new Time value using universal time; ensure that67 // the data remains consistent by setting invalid values to zero68 void Time::setTime( int h, int m, int s )69 {70 hour = ( h >= 0 && h < 24 ) ? h : 0; // validate hour71 minute = ( m >= 0 && m < 60 ) ? m : 0; // validate minute72 second = ( s >= 0 && s < 60 ) ? s : 0; // validate second73 } // end function setTime7475 // print Time in universal-time format (HH:MM:SS)76 void Time::printUniversal()77 {78 cout << setfill( '0' ) << setw( 2 ) << hour << ":" 79 << setw( 2 ) << minute << ":" << setw( 2 ) << second;80 } // end function printUniversal8182 // print Time in standard-time format (HH:MM:SS AM or PM)

cpphtp5_09_IM.fm Page 483 Thursday, December 23, 2004 4:14 PM

Page 5: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

484 Chapter 9 Classes: A Deeper Look, Part 1

83 void Time::printStandard()84 {85 cout << ( ( hour == 0 || hour == 12 ) ? 12 : hour % 12 ) << ":" 86 << setfill( '0' ) << setw( 2 ) << minute << ":" << setw( 2 )87 << second << ( hour < 12 ? " AM" : " PM" );88 } // end function printStandard8990 // check if a year is a leap year91 bool Time::isLeapYear( int y )92 {93 if ( ( y % 400 == 0 ) || ( ( y % 4 == 0 ) && ( y % 100 != 0 ) ) )94 return true;95 else96 return false;97 } // end function isLeapYear

1 // Exercise 9.4 Solution: Ex09_04.cpp2 #include <iostream>3 using std::cout;4 using std::endl;56 #include "Time.h"78 int main()9 {

10 Time t; // create Time object1112 // display current time13 cout << "The universal time is ";14 t.printUniversal();15 cout << "\nThe standard time is ";16 t.printStandard();17 cout << endl;18 return 0;19 } // end main

The universal time is 14:54:06The standard time is 2:54:06 PM

1 // Exercise 9.4 Solution: Time.h2 #ifndef TIME_H3 #define TIME_H4 5 class Time 6 {7 public:8 Time(); // constructor9 void setTime( int, int, int ); // set hour, minute and second

10 void printUniversal(); // print time in universal-time format

cpphtp5_09_IM.fm Page 484 Thursday, December 23, 2004 4:14 PM

Page 6: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 485

11 void printStandard(); // print time in standard-time format12 private:13 int hour; // 0 - 23 (24-hour clock format)14 int minute; // 0 - 5915 int second; // 0 - 5916 }; // end class Time1718 #endif

1 // Exercise 9.4 Solution: Time.cpp2 // Member-function definitions for class Time.3 #include <iostream> 4 using std::cout;56 #include <iomanip>7 using std::setfill;8 using std::setw;9

10 #include <ctime>11 using std::localtime;12 using std::time;13 using std::time_t;1415 #include "Time.h" // include definition of class Time from Time.h1617 Time::Time()18 {19 const time_t currentTime = time( 0 );20 const tm *localTime = localtime( &currentTime );21 setTime( localTime->tm_hour, localTime->tm_min, localTime->tm_sec );22 } // end Time constructor2324 // set new Time value using universal time; ensure that25 // the data remains consistent by setting invalid values to zero26 void Time::setTime( int h, int m, int s )27 {28 hour = ( h >= 0 && h < 24 ) ? h : 0; // validate hour29 minute = ( m >= 0 && m < 60 ) ? m : 0; // validate minute30 second = ( s >= 0 && s < 60 ) ? s : 0; // validate second31 } // end function setTime3233 // print Time in universal-time format (HH:MM:SS)34 void Time::printUniversal()35 {36 cout << setfill( '0' ) << setw( 2 ) << hour << ":" 37 << setw( 2 ) << minute << ":" << setw( 2 ) << second;38 } // end function printUniversal3940 // print Time in standard-time format (HH:MM:SS AM or PM)41 void Time::printStandard()42 {43 cout << ( ( hour == 0 || hour == 12 ) ? 12 : hour % 12 ) << ":" 44 << setfill( '0' ) << setw( 2 ) << minute << ":" << setw( 2 )45 << second << ( hour < 12 ? " AM" : " PM" );

cpphtp5_09_IM.fm Page 485 Thursday, December 23, 2004 4:14 PM

Page 7: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

486 Chapter 9 Classes: A Deeper Look, Part 1

9.5 (Complex Class) Create a class called Complex for performing arithmetic with complex num-bers. Write a program to test your class.

Complex numbers have the form

realPart + imaginaryPart * i

where i is

Use double variables to represent the private data of the class. Provide a constructor that enablesan object of this class to be initialized when it is declared. The constructor should contain defaultvalues in case no initializers are provided. Provide public member functions that perform the fol-lowing tasks:

a) Adding two Complex numbers: The real parts are added together and the imaginaryparts are added together.

b) Subtracting two Complex numbers: The real part of the right operand is subtracted fromthe real part of the left operand, and the imaginary part of the right operand is sub-tracted from the imaginary part of the left operand.

c) Printing Complex numbers in the form (a, b), where a is the real part and b is the imag-inary part.

ANS:

46 } // end function printStandard

1 // Exercise 9.5 Solution: Complex.h2 #ifndef COMPLEX_H3 #define COMPLEX_H45 class Complex 6 {7 public:8 Complex( double = 0.0, double = 0.0 ); // default constructor9 Complex add( const Complex & ); // function add

10 Complex subtract( const Complex & ); // function subtract11 void printComplex(); // print complex number format12 void setComplexNumber( double, double ); // set complex number 13 private:14 double realPart;15 double imaginaryPart;16 }; // end class Complex 1718 #endif

1 // Exercise 9.5 Solution: Complex.cpp2 // Member-function definitions for class Complex.3 #include <iostream> 4 using std::cout; 56 #include "Complex.h"78 Complex::Complex( double real, double imaginary )9 {

–1

cpphtp5_09_IM.fm Page 486 Thursday, December 23, 2004 4:14 PM

Page 8: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 487

10 setComplexNumber( real, imaginary ); 11 } // end Complex constructor1213 Complex Complex::add( const Complex &right )14 {15 return Complex( 16 realPart + right.realPart, imaginaryPart + right.imaginaryPart );17 } // end function add1819 Complex Complex::subtract( const Complex &right )20 {21 return Complex( 22 realPart - right.realPart, imaginaryPart - right.imaginaryPart );23 } // end function subtract2425 void Complex::printComplex()26 {27 cout << '(' << realPart << ", " << imaginaryPart << ')';28 } // end function printComplex2930 void Complex::setComplexNumber( double rp, double ip ) 31 {32 realPart = rp;33 imaginaryPart = ip;34 } // end function setComplexNumber

1 // Exercise 9.5 Solution: Ex09_05.cpp2 #include <iostream> 3 using std::cout; 4 using std::endl; 56 #include "Complex.h"78 int main()9 {

10 Complex a( 1, 7 ), b( 9, 2 ), c; // create three Complex objects 1112 a.printComplex(); // output object a13 cout << " + ";14 b.printComplex(); // output object b15 cout << " = ";16 c = a.add( b ); // invoke add function and assign to object c17 c.printComplex(); // output object c1819 cout << '\n';20 a.setComplexNumber( 10, 1 ); // reset realPart and 21 b.setComplexNumber( 11, 5 ); // and imaginaryPart 22 a.printComplex(); // output object a23 cout << " - ";24 b.printComplex(); // output object b 25 cout << " = "; 26 c = a.subtract( b ); // invoke add function and assign to object c27 c.printComplex(); // output object c28 cout << endl;

cpphtp5_09_IM.fm Page 487 Thursday, December 23, 2004 4:14 PM

Page 9: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

488 Chapter 9 Classes: A Deeper Look, Part 1

9.6 (Rational Class) Create a class called Rational for performing arithmetic with fractions.Write a program to test your class.

Use integer variables to represent the private data of the class—the numerator and the denom-inator. Provide a constructor that enables an object of this class to be initialized when it isdeclared. The constructor should contain default values in case no initializers are provided andshould store the fraction in reduced form. For example, the fraction

would be stored in the object as 1 in the numerator and 2 in the denominator. Provide publicmember functions that perform each of the following tasks:

a) Adding two Rational numbers. The result should be stored in reduced form.b) Subtracting two Rational numbers. The result should be stored in reduced form.c) Multiplying two Rational numbers. The result should be stored in reduced form.d) Dividing two Rational numbers. The result should be stored in reduced form.e) Printing Rational numbers in the form a/b, where a is the numerator and b is the de-

nominator.f) Printing Rational numbers in floating-point format.ANS:

29 return 0;30 } // end main

(1, 7) + (9, 2) = (10, 9)(10, 1) - (11, 5) = (-1, -4)

1 // Exercise 9.6 Solution: Rational.h2 #ifndef RATIONAL_H3 #define RATIONAL_H45 class Rational 6 {7 public:8 Rational( int = 0, int = 1 ); // default constructor9 Rational addition( const Rational & ); // function addition

10 Rational subtraction( const Rational & ); // function subtraction11 Rational multiplication( const Rational & ); // function multi.12 Rational division( const Rational & ); // function division13 void printRational (); // print rational format14 void printRationalAsDouble(); // print rational as double format15 private:16 int numerator; // integer numerator17 int denominator; // integer denominator18 void reduction(); // utility function19 }; // end class Rational2021 #endif

1 // Exercise 9.6 Solution: Rational.cpp2 // Member-function definitions for class Rational.3 #include <iostream>

24---

cpphtp5_09_IM.fm Page 488 Thursday, December 23, 2004 4:14 PM

Page 10: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 489

4 using std::cout; 56 #include "Rational.h" // include definition of class Rational78 Rational::Rational( int n, int d )9 {

10 numerator = n; // sets numerator11 denominator = d; // sets denominator12 reduction(); // store the fraction in reduced form13 } // end Rational constructor1415 Rational Rational::addition( const Rational &a )16 {17 Rational t; // creates Rational object1819 t.numerator = a.numerator * denominator;20 t.numerator += a.denominator * numerator; 21 t.denominator = a.denominator * denominator;22 t.reduction(); // store the fraction in reduced form23 return t;24 } // end function addition2526 Rational Rational::subtraction( const Rational &s )27 {28 Rational t; // creates Rational object 2930 t.numerator = s.denominator * numerator;31 t.numerator -= denominator * s.numerator;32 t.denominator = s.denominator * denominator;33 t.reduction(); // store the fraction in reduced form34 return t;35 } // end function subtraction3637 Rational Rational::multiplication( const Rational &m )38 {39 Rational t; // creates Rational object 4041 t.numerator = m.numerator * numerator;42 t.denominator = m.denominator * denominator;43 t.reduction(); // store the fraction in reduced form44 return t;45 } // end function multiplication4647 Rational Rational::division( const Rational &v )48 {49 Rational t; // creates Rational object 5051 t.numerator = v.denominator * numerator; 52 t.denominator = denominator * v.numerator;53 t.reduction(); // store the fraction in reduced form54 return t;55 } // end function division5657 void Rational::printRational ()58 {

cpphtp5_09_IM.fm Page 489 Thursday, December 23, 2004 4:14 PM

Page 11: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

490 Chapter 9 Classes: A Deeper Look, Part 1

59 if ( denominator == 0 ) // validates denominator60 cout << "\nDIVIDE BY ZERO ERROR!!!" << '\n';61 else if ( numerator == 0 ) // validates numerator62 cout << 0;63 else64 cout << numerator << '/' << denominator;65 } // end function printRational6667 void Rational::printRationalAsDouble() 68 { 69 cout << static_cast< double >( numerator ) / denominator; 70 } // end function printRationalAsDouble7172 void Rational::reduction()73 {74 int largest; 75 largest = numerator > denominator ? numerator : denominator;7677 int gcd = 0; // greatest common divisor7879 for ( int loop = 2; loop <= largest; loop++ )8081 if ( numerator % loop == 0 && denominator % loop == 0 )82 gcd = loop;8384 if (gcd != 0) 85 {86 numerator /= gcd;87 denominator /= gcd;88 } // end if 89 } // end function reduction

1 // Exercise 9.6 Solution: Ex09_06.cpp2 #include <iostream> 3 using std::cout; 4 using std::endl; 56 #include "Rational.h" // include definition of class Rational78 int main()9 {

10 Rational c( 2, 6 ), d( 7, 8 ), x; // creates three rational objects 1112 c.printRational(); // prints rational object c13 cout << " + ";14 d.printRational(); // prints rational object d15 x = c.addition( d ); // adds object c and d; sets the value to x1617 cout << " = ";18 x.printRational(); // prints rational object x19 cout << '\n';20 x.printRational(); // prints rational object x 21 cout << " = ";22 x.printRationalAsDouble(); // prints rational object x as double

cpphtp5_09_IM.fm Page 490 Thursday, December 23, 2004 4:14 PM

Page 12: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 491

23 cout << "\n\n";2425 c.printRational(); // prints rational object c26 cout << " - ";27 d.printRational(); // prints rational object d28 x = c.subtraction( d ); // subtracts object c and d 29 30 cout << " = ";31 x.printRational(); // prints rational object x32 cout << '\n';33 x.printRational(); // prints rational object x34 cout << " = ";35 x.printRationalAsDouble(); // prints rational object x as double36 cout << "\n\n";3738 c.printRational(); // prints rational object c39 cout << " x ";40 d.printRational(); // prints rational object d41 x = c.multiplication( d ); // multiplies object c and d42 43 cout << " = ";44 x.printRational(); // prints rational object x45 cout << '\n';46 x.printRational(); // prints rational object x47 cout << " = ";48 x.printRationalAsDouble(); // prints rational object x as double49 cout << "\n\n";5051 c.printRational(); // prints rational object c52 cout << " / ";53 d.printRational(); // prints rational object d54 x = c.division( d ); // divides object c and d55 56 cout << " = ";57 x.printRational(); // prints rational object x58 cout << '\n';59 x.printRational(); // prints rational object x60 cout << " = ";61 x.printRationalAsDouble(); // prints rational object x as double62 cout << endl;63 return 0;64 } // end main

1/3 + 7/8 = 29/2429/24 = 1.20833

1/3 - 7/8 = -13/24-13/24 = -0.541667

1/3 x 7/8 = 7/247/24 = 0.291667

1/3 / 7/8 = 8/218/21 = 0.380952

cpphtp5_09_IM.fm Page 491 Thursday, December 23, 2004 4:14 PM

Page 13: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

492 Chapter 9 Classes: A Deeper Look, Part 1

9.7 (Enhancing Class Time) Modify the Time class of Figs. 9.8–9.9 to include a tick memberfunction that increments the time stored in a Time object by one second. The Time object shouldalways remain in a consistent state. Write a program that tests the tick member function in a loopthat prints the time in standard format during each iteration of the loop to illustrate that the tickmember function works correctly. Be sure to test the following cases:

a) Incrementing into the next minute.b) Incrementing into the next hour.c) Incrementing into the next day (i.e., 11:59:59 PM to 12:00:00 AM).ANS:

1 // Exercise 9.7 Solution: Time.h2 #ifndef TIME_H3 #define TIME_H45 class Time 6 {7 public:8 public:9 Time( int = 0, int = 0, int = 0 ); // default constructor

1011 // set functions12 void setTime( int, int, int ); // set hour, minute, second13 void setHour( int ); // set hour (after validation)14 void setMinute( int ); // set minute (after validation)15 void setSecond( int ); // set second (after validation)1617 // get functions18 int getHour(); // return hour19 int getMinute(); // return minute20 int getSecond(); // return second2122 void tick(); // increment one second23 void printUniversal(); // output time in universal-time format24 void printStandard(); // output time in standard-time format25 private:26 int hour; // 0 - 23 (24-hour clock format)27 int minute; // 0 - 5928 int second; // 0 - 5929 }; // end class Time3031 #endif

1 // Exercise 9.7: Time.cpp2 // Member-function definitions for class Time.3 #include <iostream>4 using std::cout;56 #include <iomanip>7 using std::setfill;8 using std::setw;9

10 #include "Time.h" // include definition of class Time from Time.h

cpphtp5_09_IM.fm Page 492 Thursday, December 23, 2004 4:14 PM

Page 14: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 493

1112 // Time constructor initializes each data member to zero;13 // ensures that Time objects start in a consistent state 14 Time::Time( int hr, int min, int sec ) 15 { 16 setTime( hr, min, sec ); // validate and set time 17 } // end Time constructor 1819 // set new Time value using universal time; ensure that20 // the data remains consistent by setting invalid values to zero21 void Time::setTime( int h, int m, int s )22 {23 setHour( h ); // set private field hour24 setMinute( m ); // set private field minute25 setSecond( s ); // set private field second26 } // end function setTime2728 // set hour value29 void Time::setHour( int h )30 {31 hour = ( h >= 0 && h < 24 ) ? h : 0; // validate hour32 } // end function setHour3334 // set minute value35 void Time::setMinute( int m )36 {37 minute = ( m >= 0 && m < 60 ) ? m : 0; // validate minute38 } // end function setMinute3940 // set second value41 void Time::setSecond( int s )42 {43 second = ( s >= 0 && s < 60 ) ? s : 0; // validate second44 } // end function setSecond4546 // return hour value47 int Time::getHour()48 {49 return hour;50 } // end function getHour5152 // return minute value53 int Time::getMinute()54 {55 return minute;56 } // end function getMinute5758 // return second value59 int Time::getSecond()60 {61 return second;62 } // end function getSecond6364 // increment one second65 void Time::tick()

cpphtp5_09_IM.fm Page 493 Thursday, December 23, 2004 4:14 PM

Page 15: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

494 Chapter 9 Classes: A Deeper Look, Part 1

66 {67 setSecond( getSecond() + 1 ); // increment second by 16869 if ( getSecond() == 0 ) 70 {71 setMinute( getMinute() + 1 ); // increment minute by 17273 if ( getMinute() == 0 )74 setHour( getHour() + 1 ); // increment hour by 175 } // end if 76 } // end function tick7778 // print Time in universal-time format (HH:MM:SS)79 void Time::printUniversal()80 {81 cout << setfill( '0' ) << setw( 2 ) << getHour() << ":"82 << setw( 2 ) << getMinute() << ":" << setw( 2 ) << getSecond();83 } // end function printUniversal8485 // print Time in standard-time format (HH:MM:SS AM or PM)86 void Time::printStandard()87 {88 cout << ( ( getHour() == 0 || getHour() == 12 ) ? 12 : getHour() % 12 )89 << ":" << setfill( '0' ) << setw( 2 ) << getMinute()90 << ":" << setw( 2 ) << getSecond() << ( hour < 12 ? " AM" : " PM" );91 } // end function printStandard

1 // Exercise 9.7: Ex09_07.cpp2 #include <iostream> 3 using std::cout; 4 using std::endl; 56 #include "Time.h" // include definition of class Time78 const int MAX_TICKS = 30;9

10 int main()11 {12 Time t; // instantiate object t of class Time1314 t.setTime( 23, 59, 57 ); // set time1516 // output Time object t's values 17 for ( int ticks = 1; ticks < MAX_TICKS; ++ticks ) 18 {19 t.printStandard(); // invokes function printStandard20 cout << endl;21 t.tick(); // invokes function tick22 } // end for2324 return 0;25 } // end main

cpphtp5_09_IM.fm Page 494 Thursday, December 23, 2004 4:14 PM

Page 16: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 495

9.8 (Enhancing Class Date) Modify the Date class of Fig. 9.17 to perform error checking on theinitializer values for data members month, day and year. Also, provide a member function nextDayto increment the day by one. The Date object should always remain in a consistent state. Write aprogram that tests function nextDay in a loop that prints the date during each iteration to illustratethat nextDay works correctly. Be sure to test the following cases:

a) Incrementing into the next month.b) Incrementing into the next year.ANS:

11:59:57 PM11:59:58 PM11:59:59 PM12:00:00 AM12:00:01 AM...

1 // Exercise 9.8 Solution: Date.h2 #ifndef DATE_H3 #define DATE_H45 class Date 6 {7 public:8 Date( int = 1, int = 1, int = 1900 ); // default constructor9 void print(); // print function

10 void setDate( int, int, int ); // set month, day, year11 void setMonth( int ); // set month12 void setDay( int ); // set day13 void setYear( int ); // set year14 int getMonth(); // get month15 int getDay(); // get day16 int getYear(); // get year 17 void nextDay(); // next day18 private:19 int month; // 1-1220 int day; // 1-31 (except February(leap year), April, June, Sept, Nov)21 int year; // 1900+22 bool leapYear(); // leap year23 int monthDays(); // days in month 24 }; // end class Date2526 #endif

1 // Exercise 9.8 Solution: Date.cpp2 // Member-function definitions for class Date.3 #include <iostream> 4 using std::cout; 56 #include "Date.h" // include definition of class Date

cpphtp5_09_IM.fm Page 495 Thursday, December 23, 2004 4:14 PM

Page 17: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

496 Chapter 9 Classes: A Deeper Look, Part 1

78 Date::Date( int m, int d, int y ) 9 {

10 setDate( m, d, y ); // sets date 11 } // end Date constructor1213 void Date::setDate( int mo, int dy, int yr )14 {15 setMonth( mo ); // invokes function setMonth 16 setDay( dy ); // invokes function setDay17 setYear( yr ); // invokes function setYear18 } // end function setDate1920 void Date::setDay( int d )21 {22 if ( month == 2 && leapYear() ) 23 day = ( d <= 29 && d >= 1 ) ? d : 1; 24 else25 day = ( d <= monthDays() && d >= 1 ) ? d : 1;26 } // end function setDay2728 void Date::setMonth( int m ) 29 { 30 month = m <= 12 && m >= 1 ? m : 1; // sets month 31 } // end function setMonth3233 void Date::setYear( int y ) 34 {35 year = y >= 1900 ? y : 1900; // sets year36 } // end function setYear3738 int Date::getDay() 39 {40 return day;41 } // end function getDay4243 int Date::getMonth() 44 { 45 return month; 46 } // end function getMonth4748 int Date::getYear() 49 { 50 return year; 51 } // end function getYear5253 void Date::print()54 {55 cout << month << '-' << day << '-' << year << '\n'; // outputs date56 } // end function print5758 void Date::nextDay()59 {60 setDay( day + 1 ); // increments day by 161

cpphtp5_09_IM.fm Page 496 Thursday, December 23, 2004 4:14 PM

Page 18: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 497

62 if ( day == 1 ) 63 {64 setMonth( month + 1 ); // increments month by 16566 if ( month == 1 )67 setYear( year + 1 ); // increments year by 168 } // end if statement 69 } // end function nextDay7071 bool Date::leapYear()72 {73 if ( year % 400 == 0 || ( year % 4 == 0 && year % 100 != 0 ) )74 return true; // is a leap year75 else76 return false; // is not a leap year77 } // end function leapYear7879 int Date::monthDays()80 {81 const int days[ 12 ] = 82 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };8384 return month == 2 && leapYear() ? 29 : days[ month - 1 ];85 } // end function monthDays

1 // Exercise 9.8 Solution: Ex09_08.cpp2 #include <iostream> 3 using std::cout; 4 using std::endl; 56 #include "Date.h" // include definitions of class Date78 int main()9 {

10 const int MAXDAYS = 16;11 Date d( 12, 24, 2004 ); // instantiate object d of class Date1213 // output Date object d's value14 for ( int loop = 1; loop <= MAXDAYS; ++loop ) 15 {16 d.print(); // invokes function print17 d.nextDay(); // invokes function next day18 } // end for1920 cout << endl;21 return 0;22 } // end main

cpphtp5_09_IM.fm Page 497 Thursday, December 23, 2004 4:14 PM

Page 19: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

498 Chapter 9 Classes: A Deeper Look, Part 1

9.9 (Combining Class Time and Class Date) Combine the modified Time class of Exercise 9.7 andthe modified Date class of Exercise 9.8 into one class called DateAndTime. (In Chapter 12, we willdiscuss inheritance, which will enable us to accomplish this task quickly without modifying the ex-isting class definitions.) Modify the tick function to call the nextDay function if the time incre-ments into the next day. Modify functions printStandard and printUniversal to output the dateand time. Write a program to test the new class DateAndTime. Specifically, test incrementing thetime into the next day.

ANS:

12-24-200412-25-200412-26-200412-27-200412-28-200412-29-200412-30-200412-31-20041-1-20051-2-20051-3-20051-4-20051-5-20051-6-20051-7-20051-8-2005

1 // Exercise 9.9 Solution: DateAndTime.h2 #ifndef DATEANDTIME_H3 #define DATEANDTIME_H45 class DateAndTime 6 {7 public:8 DateAndTime( int = 1, int = 1, int = 1900, 9 int = 0, int = 0, int = 0 ); // default constructor

10 void setDate( int, int, int ); // set month, day, year11 void setMonth( int ); // set month12 void setDay( int ); // set day13 void setYear( int ); // set year14 void nextDay(); // next day15 void setTime( int, int, int ); // set hour, minute, second16 void setHour( int ); // set hour17 void setMinute( int ); // set minute 18 void setSecond( int ); // set second19 void tick(); // tick function 20 int getMonth(); // get month21 int getDay(); // get day22 int getYear(); // get year23 int getHour(); // get hour24 int getMinute(); // get minute25 int getSecond(); // get second 26 void printStandard(); // print standard time

cpphtp5_09_IM.fm Page 498 Thursday, December 23, 2004 4:14 PM

Page 20: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 499

27 void printUniversal(); // print universal time28 private:29 int month; // 1-12 30 int day; // 1-31 (except February(leap year), April, June, Sept, Nov)31 int year; // 1900+32 int hour; // 0-23 (24 hour clock format)33 int minute; // 0-59 34 int second; // 0-5935 bool leapYear(); // leap year36 int monthDays(); // days in month 37 }; // end class DateAndTime3839 #endif

1 // Exercise 9.9 Solution: DateAndTime.cpp2 // Member function definitions for class DateAndTime.3 #include <iostream> 4 using std::cout; 5 using std::endl;67 #include "DateAndTime.h" // include definition of class DateAndTime89 DateAndTime::DateAndTime(

10 int m, int d, int y, int hr, int min, int sec )11 {12 setDate( m, d, y ); // sets date13 setTime( hr, min, sec ); // sets time14 } // end DateAndTime constructor1516 void DateAndTime::setDate( int mo, int dy, int yr )17 { 18 setMonth( mo ); // invokes function setMonth19 setDay( dy ); // invokes function setday20 setYear( yr ); // invokes function setYear 21 } // end function setDate2223 void DateAndTime::setDay( int d )24 {25 if ( month == 2 && leapYear() )26 day = ( d <= 29 && d >= 1 ) ? d : 1;27 else28 day = ( d <= monthDays() && d >= 1 ) ? d : 1;29 } // end function setDay3031 void DateAndTime::setMonth( int m ) 32 { 33 month = m <= 12 && m >= 1 ? m : 1; // sets month34 } // end function setMonth3536 void DateAndTime::setYear( int y ) 37 { 38 year = y >= 1900 ? y : 1900; // sets year39 } // end function setYear40

cpphtp5_09_IM.fm Page 499 Thursday, December 23, 2004 4:14 PM

Page 21: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

500 Chapter 9 Classes: A Deeper Look, Part 1

41 void DateAndTime::nextDay()42 {43 setDay( day + 1 ); // increments day by 14445 if ( day == 1 ) 46 {47 setMonth( month + 1 ); // increments month by 14849 if ( month == 1 )50 setYear( year + 1 ); // increments year by 151 } // end if statement 52 } //end function nextDay5354 void DateAndTime::setTime( int hr, int min, int sec )55 {56 setHour( hr ); // invokes function setHour57 setMinute( min ); // invokes function setMinute58 setSecond( sec ); // invokes function setSecond59 } // end function setTime6061 void DateAndTime::setHour( int h ) 62 { 63 hour = ( h >= 0 && h < 24 ) ? h : 0; // sets hour 64 } // end function setHour6566 void DateAndTime::setMinute( int m ) 67 { 68 minute = ( m >= 0 && m < 60 ) ? m : 0; // sets minute69 } // end function setMinute7071 void DateAndTime::setSecond( int s ) 72 { 73 second = ( s >= 0 && s < 60 ) ? s : 0; // sets second74 } // end function setSecond7576 void DateAndTime::tick()77 {78 setSecond( second + 1 ); // increments second by 17980 if ( second == 0 ) 81 {82 setMinute( minute + 1 ); // increments minute by 18384 if ( minute == 0 ) 85 {86 setHour( hour + 1 ); // increments hour by 18788 if ( hour == 0 )89 nextDay(); // increments day by 190 } // end if 91 } // end if 92 } // end function tick9394 int DateAndTime::getDay() 95 {

cpphtp5_09_IM.fm Page 500 Thursday, December 23, 2004 4:14 PM

Page 22: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 501

96 return day; 97 } // end function getDay9899 int DateAndTime::getMonth()100 {101 return month; 102 } // end function getMonth103104 int DateAndTime::getYear() 105 { 106 return year; 107 } // end function getYear108109 int DateAndTime::getHour() 110 { 111 return hour; 112 } // end function getHour113114 int DateAndTime::getMinute() 115 { 116 return minute; 117 } // end function getMinute118119 int DateAndTime::getSecond() 120 { 121 return second; 122 } // end function getSecond123124 void DateAndTime::printStandard()125 {126 cout << ( ( hour % 12 == 0 ) ? 12 : hour % 12 ) << ':'127 << ( minute < 10 ? "0" : "" ) << minute << ':'128 << ( second < 10 ? "0" : "" ) << second129 << ( hour < 12 ? " AM " : " PM " )130 << month << '-' << day << '-' << year << endl;131 } // end function printStandard132133 void DateAndTime::printUniversal()134 {135 cout << ( hour < 10 ? "0" : "" ) << hour << ':'136 << ( minute < 10 ? "0" : "" ) << minute << ':'137 << ( second < 10 ? "0" : "" ) << second << " "138 << month << '-' << day << '-' << year << endl;139 } // end function printUniversal140141 bool DateAndTime::leapYear()142 {143 if ( year % 400 == 0 || ( year % 4 == 0 && year % 100 != 0 ) )144 return true; // is a leap year145 else146 return false; // is not a leap year147 } // end function leapYear148149 int DateAndTime::monthDays()150 {

cpphtp5_09_IM.fm Page 501 Thursday, December 23, 2004 4:14 PM

Page 23: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

502 Chapter 9 Classes: A Deeper Look, Part 1

9.10 (Returning Error Indicators from Class Time’s set Functions) Modify the set functions in theTime class of Figs. 9.8–9.9 to return appropriate error values if an attempt is made to set a data mem-

151 const int days[ 12 ] = { 152 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };153154 return ( month == 2 && leapYear() ) ? 29 : days[ ( month - 1 ) ];155 } // end function monthDays

1 // Exercise 9.9 Solution: Ex09_09.cpp2 #include <iostream> 3 using std::cout; 4 using std::endl; 56 #include "DateAndTime.h" // include definitions of class DateAndTime78 int main()9 {

10 const int MAXTICKS = 30;11 DateAndTime d( 12, 31, 2004, 23, 59, 57 ); // instantiates object d 12 // of class DateAndTime13 14 for ( int ticks = 1; ticks <= MAXTICKS; ticks++ ) 15 {16 cout << "Universal time: ";17 d.printUniversal(); // invokes function printUniversal18 cout << "Standard time: ";19 d.printStandard(); // invokes function printStandard20 d.tick(); // invokes function tick21 } // end for2223 cout << endl;24 return 0;25 } // end main

Universal time: 23:59:57 12-31-2004Standard time: 11:59:57 PM 12-31-2004Universal time: 23:59:58 12-31-2004Standard time: 11:59:58 PM 12-31-2004Universal time: 23:59:59 12-31-2004Standard time: 11:59:59 PM 12-31-2004Universal time: 00:00:00 1-1-2005Standard time: 12:00:00 AM 1-1-2005Universal time: 00:00:01 1-1-2005Standard time: 12:00:01 AM 1-1-2005...

cpphtp5_09_IM.fm Page 502 Thursday, December 23, 2004 4:14 PM

Page 24: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 503

ber of an object of class Time to an invalid value. Write a program that tests your new version of classTime. Display error messages when set functions return error values.

ANS:

1 // Exercise 9.10 Solution: Time.h2 #ifndef TIME_H3 #define TIME_H45 class Time 6 {7 public:8 Time( int = 0, int = 0, int = 0 ); // default constructor9 bool setTime( int, int, int ); // set hour, minute, second

10 bool setHour( int ); // set hour11 bool setMinute( int ); // set minute12 bool setSecond( int ); // set second13 int getHour(); // get hour14 int getMinute(); // get minute15 int getSecond(); // get second16 void printUniversal(); // print universal time17 void printStandard(); // print standard time18 private:19 int hour; // 0-2320 int minute; // 0-5921 int second; // 0-5922 }; // end class Time2324 #endif

1 // Exercise 9.10 Solution: Time.cpp2 // Member-function definitions for class Time.3 #include <iostream> 4 using std::cout; 56 #include "Time.h" // include definition of class Time78 Time::Time( int hr, int min, int sec ) 9 {

10 setTime( hr, min, sec ); 11 } // end Time constructor1213 bool Time::setTime( int h, int m, int s )14 {15 bool hourValid = setHour( h ); // invokes function setHour 16 bool minuteValid = setMinute( m ); // invokes function setMinute17 bool secondValid = setSecond( s ); // invokes function setSecond18 return hourValid && minuteValid && secondValid;19 } // end function setTime 2021 bool Time::setHour( int hr )22 {23 if ( hr >= 0 && hr < 24 ) 24 {

cpphtp5_09_IM.fm Page 503 Thursday, December 23, 2004 4:14 PM

Page 25: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

504 Chapter 9 Classes: A Deeper Look, Part 1

25 hour = hr;26 return true; // hour is valid27 } // end if28 else 29 {30 hour = 0;31 return false; // hour is invalid32 } // end else33 } // end function setHour3435 bool Time::setMinute( int min )36 {37 if ( min >= 0 && min < 60 ) 38 {39 minute = min;40 return true; // minute is valid41 } // end if42 else 43 {44 minute = 0;45 return false; // minute is invalid46 } // end else47 } // end function setMinute4849 bool Time::setSecond( int sec )50 {51 if ( sec >= 0 && sec < 60 ) 52 {53 second = sec;54 return true; // second is valid55 } // end if56 else 57 {58 second = 0;59 return false; // second is invalid60 } // end else61 } // end function setSecond6263 // return hour value64 int Time::getHour()65 {66 return hour;67 } // end function getHour6869 // return minute value70 int Time::getMinute()71 {72 return minute;73 } // end function getMinute7475 // return second value76 int Time::getSecond()77 {78 return second;79 } // end function getSecond

cpphtp5_09_IM.fm Page 504 Thursday, December 23, 2004 4:14 PM

Page 26: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 505

8081 void Time::printUniversal()82 {83 cout << ( hour < 10 ? "0" : "" ) << hour << ':'84 << ( minute < 10 ? "0" : "" ) << minute << ':'85 << ( second < 10 ? "0" : "" ) << second;86 } // end function printUniversal8788 void Time::printStandard() 89 {90 cout << ( ( hour % 12 == 0 ) ? 12 : hour % 12 ) << ':'91 << ( minute < 10 ? "0": "" ) << minute << ':'92 << ( second < 10 ? "0": "" ) << second93 << ( hour < 12 ? " AM" : " PM" );94 } // end function printStandard

1 // Exercise 9.10 Solution: Ex09_10.cpp2 #include <iostream> 3 using std::cin;4 using std::cout; 5 using std::endl; 67 #include "Time.h" // include definition of class Time89 int main()

10 {11 Time time; // the Time object121314 // all t1 object's times are valid15 if ( !t1.getInvalidTime() )16 cout << "Error: invalid time setting(s) attempted." << '\n'17 << "Invalid setting(s) changed to zero." << '\n';1819 t1.printStandard(); // invokes function print standard2021 // object t2 has invalid time settings22 if ( !t2.getInvalidTime() )23 cout << "\nError: invalid time setting(s) attempted.\n"24 << "Invalid setting(s) changed to zero.\n";2526 t2.printUniversal(); // invokes function print universal27 cout << endl;2829 return 0;30 } // end main

1 // Exercise 9.10 Solution: Ex09_10.cpp2 #include <iostream> 3 using std::cin;4 using std::cout; 5 using std::endl; 6

cpphtp5_09_IM.fm Page 505 Thursday, December 23, 2004 4:14 PM

Page 27: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

506 Chapter 9 Classes: A Deeper Look, Part 1

7 #include "Time.h" // include definition of class Time89 int getMenuChoice(); // prototype

1011 int main()12 {13 Time time; // the Time object14 int choice = getMenuChoice();15 int hours;16 int minutes;17 int seconds;18 19 while ( choice != 4 )20 {21 switch ( choice )22 {23 case 1: // set hour24 cout << "Enter Hours: ";25 cin >> hours;26 27 if ( !time.setHour( hours ) )28 cout << "Invalid hours." << endl;29 break;30 case 2: // set minute31 cout << "Enter Minutes: ";32 cin >> minutes;33 34 if ( !time.setMinute( minutes ) )35 cout << "Invalid minutes." << endl;36 break;37 case 3: // set seconds38 cout << "Enter Seconds: ";39 cin >> seconds;40 41 if ( !time.setSecond( seconds ) )42 cout << "Invalid seconds." << endl;43 break;44 } // end switch45 46 cout << "Hour: " << time.getHour() << " Minute: " 47 << time.getMinute() << " Second: " << time.getSecond() << endl;48 cout << "Universal time: ";49 time.printUniversal();50 cout << " Standard time: ";51 time.printStandard();52 cout << endl;5354 choice = getMenuChoice();55 } // end while 56 } // end main5758 // prints a menu and returns a value corresponding to the menu choice59 int getMenuChoice()60 {61 int choice;

cpphtp5_09_IM.fm Page 506 Thursday, December 23, 2004 4:14 PM

Page 28: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 507

9.11 (Rectangle Class) Create a class Rectangle with attributes length and width, each of whichdefaults to 1. Provide member functions that calculate the perimeter and the area of the rectangle.Also, provide set and get functions for the length and width attributes. The set functions should ver-ify that length and width are each floating-point numbers larger than 0.0 and less than 20.0.

ANS:

6263 cout << "1. Set Hour\n2. Set Minute\n3. Set Second\n"64 << "4. Exit\nChoice: " << endl;65 cin >> choice;66 return choice;67 } // end function getMenuChoice

1. Set Hour2. Set Minute3. Set Second4. ExitChoice:1Enter Hours: 17Hour: 17 Minute: 0 Second: 0Universal time: 17:00:00 Standard time: 5:00:00 PM1. Set Hour2. Set Minute3. Set Second4. ExitChoice:2Enter Minutes: 65Invalid minutes.Hour: 17 Minute: 0 Second: 0Universal time: 17:00:00 Standard time: 5:00:00 PM1. Set Hour2. Set Minute3. Set Second4. ExitChoice:3Enter Seconds: 23Hour: 17 Minute: 0 Second: 23Universal time: 17:00:23 Standard time: 5:00:23 PM1. Set Hour2. Set Minute3. Set Second4. ExitChoice:4

1 // Exercise 9.11 Solution: Rectangle.h2 #ifndef RECTANGLE_H3 #define RECTANGLE_H45 class Rectangle 6 {

cpphtp5_09_IM.fm Page 507 Thursday, December 23, 2004 4:14 PM

Page 29: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

508 Chapter 9 Classes: A Deeper Look, Part 1

7 public:8 Rectangle( double = 1.0, double = 1.0 ); // default constructor9 void setWidth( double w ); // set width

10 void setLength( double l ); // set length11 double getWidth(); // get width12 double getLength(); // get length 13 double perimeter(); // perimeter14 double area(); // area15 private:16 double length; // 1.0 < length < 20.017 double width; // 1.0 < width < 20.018 }; // end class Rectangle1920 #endif

1 // Exercise 9.11 Solution: Rectangle.cpp2 // Member-function definitions for class Rectangle.34 #include "Rectangle.h" // include definition of class Rectangle56 Rectangle::Rectangle( double w, double l )7 {8 setWidth(w); // invokes function setWidth9 setLength(l); // invokes function setLength

10 } // end Rectangle constructor1112 void Rectangle::setWidth( double w ) 13 { 14 width = w > 0 && w < 20.0 ? w : 1.0; // sets width15 } // end function setWidth1617 void Rectangle::setLength( double l ) 18 { 19 length = l > 0 && l < 20.0 ? l : 1.0; // sets length 20 } // end function setLength2122 double Rectangle::getWidth() 23 { 24 return width; 25 } // end function getWidth2627 double Rectangle::getLength() 28 {29 return length; 30 } // end fucntion getLength3132 double Rectangle::perimeter() 33 { 34 return 2 * ( width + length ); // returns perimeter35 } // end function perimeter3637 double Rectangle::area() 38 { 39 return width * length; // returns area

cpphtp5_09_IM.fm Page 508 Thursday, December 23, 2004 4:14 PM

Page 30: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 509

9.12 (Enhancing Class Rectangle) Create a more sophisticated Rectangle class than the one youcreated in Exercise 9.11. This class stores only the Cartesian coordinates of the four corners of therectangle. The constructor calls a set function that accepts four sets of coordinates and verifies thateach of these is in the first quadrant with no single x- or y-coordinate larger than 20.0. The set func-tion also verifies that the supplied coordinates do, in fact, specify a rectangle. Provide member func-tions that calculate the length, width, perimeter and area. The length is the larger of the twodimensions. Include a predicate function square that determines whether the rectangle is a square.

ANS:

40 } // end function area

1 // Exercise 9.11 Solution: Ex09_11.cpp2 #include <iostream> 3 using std::cout; 4 using std::endl; 5 using std::fixed; 67 #include <iomanip> 8 using std::setprecision; 9

10 #include "Rectangle.h" // include definition of class Rectangle1112 int main()13 {14 Rectangle a, b( 4.0, 5.0 ), c( 67.0, 888.0 );15 16 cout << fixed;17 cout << setprecision( 1 );18 19 // output Rectangle a20 cout << "a: length = " << a.getLength() << "; width = " 21 << a.getWidth() << "; perimeter = " << a.perimeter() 22 << "; area = " << a.area() << '\n';2324 // output Rectangle b25 cout << "b: length = " << b.getLength() << "; width = " 26 << b.getWidth() << "; perimeter = " << b.perimeter() 27 << "; area = " << b.area() << '\n';2829 // output Rectangle c; bad values attempted30 cout << "c: length = " << c.getLength() << "; width = " 31 << c.getWidth() << "; perimeter = " << c.perimeter()32 << "; area = " << c.area() << endl;33 return 0;34 } // end main

a: length = 1.0; width = 1.0; perimeter = 4.0; area = 1.0b: length = 5.0; width = 4.0; perimeter = 18.0; area = 20.0c: length = 1.0; width = 1.0; perimeter = 4.0; area = 1.0

1 // Exercise 9.12 Solution: Point.h

cpphtp5_09_IM.fm Page 509 Thursday, December 23, 2004 4:14 PM

Page 31: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

510 Chapter 9 Classes: A Deeper Look, Part 1

2 #ifndef POINT_H3 #define POINT_H45 class Point 6 {7 public:8 Point( double = 0.0, double = 0.0 ); // default constructor9

10 // set and get functions11 void setX( double );12 void setY( double );13 double getX(); 14 double getY(); 15 private:16 double x; // 0.0 <= x <= 20.017 double y; // 0.0 <= y <= 20.018 }; // end class Point 1920 #endif

1 // Exercise 9.12 Solution: Point.cpp2 // Member-function definitions for class Point.34 #include "Point.h" // include definition of class Point56 Point::Point( double xCoord, double yCoord )7 {8 setX( xCoord ); // invoke function setX9 setY( yCoord ); // invoke function setY

10 } // end Point constructor1112 // set x coordinate13 void Point::setX( double xCoord )14 {15 x = ( xCoord >= 0.0 && xCoord <= 20.0 ) ? xCoord : 0.0;16 } // end function setX1718 // set y coordinate19 void Point::setY( double yCoord )20 {21 y = ( yCoord >= 0.0 && yCoord <= 20.0 ) ? yCoord : 0.0;22 } // end function setY2324 // return x coordinate25 double Point::getX()26 {27 return x;28 } // end function getX2930 // return y coordinate31 double Point::getY()32 {33 return y;

cpphtp5_09_IM.fm Page 510 Thursday, December 23, 2004 4:14 PM

Page 32: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 511

34 } // end function getY

1 // Exercise 9.12 Solution: Rectangle.h2 #ifndef RECTANGLE_H3 #define RECTANGLE_H45 #include "Point.h" // include definition of class Point67 class Rectangle 8 {9 public:

10 // default constructor11 Rectangle( Point = Point( 0.0, 1.0 ), Point = Point( 1.0, 1.0 ),12 Point = Point( 1.0, 0.0 ), Point = Point( 0.0, 0.0 ) ); 13 14 // sets x, y, x2, y2 coordinates15 void setCoord( Point, Point, Point, Point );16 double length(); // length17 double width(); // width18 void perimeter(); // perimeter19 void area(); // area20 bool square(); // square21 private:22 Point point1; 23 Point point2; 24 Point point3; 25 Point point4; 26 }; // end class Rectangle 2728 #endif

1 // Exercise 9.12 Solution: Rectangle.cpp2 // Member-function definitions for class Rectangle.3 #include <iostream> 4 using std::cout; 5 using std::endl;67 #include <iomanip> 8 using std::fixed; 9 using std::setprecision;

1011 #include <cmath>12 using std::fabs;1314 #include "Rectangle.h" // include definition of class Rectangle1516 Rectangle::Rectangle( Point a, Point b, Point c, Point d )17 {18 setCoord( a, b, c, d ); // invokes function setCoord19 } // end Rectangle constructor2021 void Rectangle::setCoord( Point p1, Point p2, Point p3, Point p4 )22 {

cpphtp5_09_IM.fm Page 511 Thursday, December 23, 2004 4:14 PM

Page 33: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

512 Chapter 9 Classes: A Deeper Look, Part 1

23 // Arrangement of points24 // p4.........p325 // . .26 // . .27 // p1.........p22829 // verify that points form a rectangle30 if ( ( p1.getY() == p2.getY() && p1.getX() == p4.getX()31 && p2.getX() == p3.getX() && p3.getY() == p4.getY() ) ) 32 {33 point1 = p1;34 point2 = p2;35 point3 = p3;36 point4 = p4;37 } // end if38 else39 {40 cout << "Coordinates do not form a rectangle!\n"41 << "Use default values.\n";42 point1 = Point( 0.0, 1.0 );43 point2 = Point( 1.0, 1.0 );44 point3 = Point( 1.0, 0.0 );45 point4 = Point( 0.0, 0.0 );46 } // end else47 } // end function setCoord4849 double Rectangle::length()50 {51 double side1 = fabs( point4.getY() - point1.getY() ); // get side152 double side2 = fabs( point2.getX() - point1.getX() ); // get side253 double length = ( side1 > side2 ? side1 : side2 );54 return length;55 } // end function length5657 double Rectangle::width()58 {59 double side1 = fabs( point4.getY() - point1.getY() ); // get side160 double side2 = fabs( point2.getX() - point1.getX() ); // get side261 double width = ( side1 < side2 ? side1 : side2 );62 return width;63 } // end function width6465 void Rectangle::perimeter()66 {67 cout << fixed << "\nThe perimeter is: " << setprecision( 1 )68 << 2 * ( length() + width() ) << endl; 69 } // end function perimeter7071 void Rectangle::area()72 {73 cout << fixed << "The area is: " << setprecision( 1 ) 74 << length() * width() << endl;75 } // end function area7677 bool Rectangle::square()

cpphtp5_09_IM.fm Page 512 Thursday, December 23, 2004 4:14 PM

Page 34: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 513

78 {79 return ( fabs( point4.getY() - point1.getY() ) == 80 fabs( point2.getX() - point1.getX() ) );81 } // end function square

1 // Exercise 9.12 Solution: Ex09_12.cpp2 #include <iostream>3 using std::cout;45 #include "Rectangle.h" // include definition of class Rectangle67 int main()8 {9 Point w( 1.0, 1.0 );

10 Point x( 5.0, 1.0 );11 Point y( 5.0, 3.0 ); 12 Point z( 1.0, 3.0 );13 Point j( 0.0, 0.0 ); 14 Point k( 1.0, 0.0 );15 Point m( 1.0, 1.0 ); 16 Point n( 0.0, 1.0 );17 Point v( 99.0, -2.3 );1819 Rectangle rectangles[ 4 ]; // array stores four rectangles2021 // output rectangles 22 for ( int i = 0; i < 4; i++ )23 {24 cout << "Rectangle" << i + 1 << ":\n";2526 switch ( i ) // initialize four different rectangles27 {28 case 0: // first rectangle29 rectangles[ i ] = Rectangle( z, y, x, w );30 break;31 case 1: // second rectangle32 rectangles[ i ] = Rectangle( j, k, m, n );33 break;34 case 2: // third rectangle35 rectangles[ i ] = Rectangle( w, x, m, n );36 break;37 case 3: // fourth rectangle38 rectangles[ i ] = Rectangle( v, x, y, z );39 break;40 } // end switch4142 cout << "length = " << rectangles[ i ].length();43 cout << "\nwidth = " << rectangles[ i ].width();44 rectangles[ i ].perimeter();45 rectangles[ i ].area();46 cout << "The rectangle " 47 << ( rectangles[ i ].square() ? "is" : "is not" )48 << " a square.\n";49 } // end for

cpphtp5_09_IM.fm Page 513 Thursday, December 23, 2004 4:14 PM

Page 35: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

514 Chapter 9 Classes: A Deeper Look, Part 1

9.13 (Enhancing Class Rectangle) Modify class Rectangle from Exercise 9.12 to include a drawfunction that displays the rectangle inside a 25-by-25 box enclosing the portion of the first quadrantin which the rectangle resides. Include a setFillCharacter function to specify the character out ofwhich the body of the rectangle will be drawn. Include a setPerimeterCharacter function to specifythe character that will be used to draw the border of the rectangle. If you feel ambitious, you mightinclude functions to scale the size of the rectangle, rotate it, and move it around within the desig-nated portion of the first quadrant.

ANS:

5051 return 0;52 } // end main

Rectangle1:length = 4width = 2The perimeter is: 12.0The area is: 8.0The rectangle is not a square.Rectangle2:length = 1.0width = 1.0The perimeter is: 4.0The area is: 1.0The rectangle is a square.Rectangle3:Coordinates do not form a rectangle!Use default values.length = 1.0width = 1.0The perimeter is: 4.0The area is: 1.0The rectangle is a square.Rectangle4:Coordinates do not form a rectangle!Use default values.length = 1.0width = 1.0The perimeter is: 4.0The area is: 1.0The rectangle is a square.

1 // Exercise 9.13 Solution: Rectangle.h2 #ifndef RECTANGLE_H3 #define RECTANGLE_H45 #include "Point.h" // include definition of class Point67 class Rectangle 8 {9 public:

10 // default constructor11 Rectangle( Point = Point( 0.0, 1.0 ), Point = Point( 1.0, 1.0 ),12 Point = Point( 1.0, 0.0 ), Point = Point( 0.0, 0.0 ),

cpphtp5_09_IM.fm Page 514 Thursday, December 23, 2004 4:14 PM

Page 36: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 515

13 char = '*', char = '*' );14 15 // sets x, y, x2, y2 coordinates16 void setCoord( Point, Point, Point, Point );17 double length(); // length18 double width(); // width19 void perimeter(); // perimeter20 void area(); // area21 bool square(); // square22 void draw(); // draw rectangle23 void setPerimeterCharacter( char ); // set perimeter character24 void setFillCharacter( char ); // set fill character25 private:26 Point point1; 27 Point point2; 28 Point point3; 29 Point point4; 30 char fillCharacter;31 char perimeterCharacter;32 }; // end class Rectangle 3334 #endif

1 // Exercise 9.13 Solution: Rectangle.cpp2 // Member-function definitions for class Rectangle.3 #include <iostream> 4 using std::cout; 5 using std::endl;67 #include <iomanip> 8 using std::fixed; 9 using std::setprecision;

1011 #include <cmath>12 using std::fabs;1314 #include "Rectangle.h" // include definition of class Rectangle1516 Rectangle::Rectangle( Point a, Point b, Point c, Point d, 17 char fillChar, char perimeterChar )18 {19 setCoord( a, b, c, d ); // invoke function setCoord20 setFillCharacter( fillChar ); // set fill character21 setPerimeterCharacter( perimeterChar ); // set perimeter character22 } // end Rectangle constructor2324 void Rectangle::setCoord( Point p1, Point p2, Point p3, Point p4 )25 {26 // Arrangement of points27 // p4.........p328 // . .29 // . .30 // p1.........p231

cpphtp5_09_IM.fm Page 515 Thursday, December 23, 2004 4:14 PM

Page 37: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

516 Chapter 9 Classes: A Deeper Look, Part 1

32 // verify that points form a rectangle33 if ( ( p1.getY() == p2.getY() && p1.getX() == p4.getX()34 && p2.getX() == p3.getX() && p3.getY() == p4.getY() ) ) 35 {36 point1 = p1;37 point2 = p2;38 point3 = p3;39 point4 = p4;40 } // end if41 else42 {43 cout << "Coordinates do not form a rectangle!\n"44 << "Use default values.\n";45 point1 = Point( 0.0, 1.0 );46 point2 = Point( 1.0, 1.0 );47 point3 = Point( 1.0, 0.0 );48 point4 = Point( 0.0, 0.0 );49 } // end else50 } // end function setCoord5152 double Rectangle::length()53 {54 double side1 = fabs( point4.getY() - point1.getY() ); // get side155 double side2 = fabs( point2.getX() - point1.getX() ); // get side256 double length = ( side1 > side2 ? side1 : side2 );57 return length;58 } // end function length5960 double Rectangle::width()61 {62 double side1 = fabs( point4.getY() - point1.getY() ); // get side163 double side2 = fabs( point2.getX() - point1.getX() ); // get side264 double width = ( side1 < side2 ? side1 : side2 );65 return width;66 } // end function width6768 void Rectangle::perimeter()69 {70 cout << fixed << "\nThe perimeter is: " << setprecision( 1 )71 << 2 * ( length() + width() ) << endl; 72 } // end function perimeter7374 void Rectangle::area()75 {76 cout << fixed << "The area is: " << setprecision( 1 ) 77 << length() * width() << endl;78 } // end function area7980 bool Rectangle::square() 81 {82 return ( fabs( point4.getY() - point1.getY() ) == 83 fabs( point2.getX() - point1.getX() ) );84 } // end function square8586 // draw rectangle

cpphtp5_09_IM.fm Page 516 Thursday, December 23, 2004 4:14 PM

Page 38: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 517

87 void Rectangle::draw() 88 {89 for ( double y = 25.0; y >= 0.0; y-- ) 90 {91 for ( double x = 0.0; x <= 25.0; x++ ) 92 {93 if ( ( point1.getX() == x && point1.getY() == y ) ||94 ( point4.getX() == x && point4.getY() == y ) ) 95 {96 // print horizontal perimeter of rectangle97 while ( x <= point2.getX() ) 98 {99 cout << perimeterCharacter;100 x++;101 } // end while102103 cout << '.'; // print remainder of quadrant104 } // end if105 else if ( ( ( x <= point4.getX() && x >= point1.getX() ) ) &&106 point4.getY() >= y && point1.getY() <= y ) 107 {108 cout << perimeterCharacter;109110 // fill inside of rectangle111 for ( x++; x < point2.getX(); ) 112 {113 cout << fillCharacter;114 x++;115 } // end for116117 cout << perimeterCharacter;118 } // end else if119 else120 cout << '.'; // print quadrant background121 } // end for122123 cout << '\n';124 } // end for125 } // end function draw126127 // set fill character128 void Rectangle::setFillCharacter( char fillChar )129 {130 fillCharacter = fillChar;131 } // end function setFillCharacter132133 // set perimeter character134 void Rectangle::setPerimeterCharacter( char perimeterChar )135 {136 perimeterCharacter = perimeterChar;137 } // end function setPerimeterCharacter

1 // Exercise 9.13 Solution: Ex09_13.cpp2

cpphtp5_09_IM.fm Page 517 Thursday, December 23, 2004 4:14 PM

Page 39: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

518 Chapter 9 Classes: A Deeper Look, Part 1

9.14 (HugeInteger Class) Create a class HugeInteger that uses a 40-element array of digits tostore integers as large as 40 digits each. Provide member functions input, output, add and sub-stract. For comparing HugeInteger objects, provide functions isEqualTo, isNotEqualTo, isGrea-terThan, isLessThan, isGreaterThanOrEqualTo and isLessThanOrEqualTo—each of these is a“predicate” function that simply returns true if the relationship holds between the two Huge-Integers and returns false if the relationship does not hold. Also, provide a predicate function is-Zero. If you feel ambitious, provide member functions multiply, divide and modulus.

ANS:

3 #include "Rectangle.h" // include definition of class Rectangle45 int main()6 {7 Point point1( 12.0, 12.0 );8 Point point2( 18.0, 12.0 );9 Point point3( 18.0, 20.0 );

10 Point point4( 12.0, 20.0 );11 Rectangle rectangle( point1, point2, point3, point4, '?', '*' ); 12 rectangle.draw(); // invokes function draw13 return 0;14 } // end main

..........................

..........................

..........................

..........................

..........................

............*******.......

............*?????*.......

............*?????*.......

............*?????*.......

............*?????*.......

............*?????*.......

............*?????*.......

............*?????*.......

............*******.......

..........................

..........................

..........................

..........................

..........................

..........................

..........................

..........................

..........................

..........................

..........................

..........................

1 // Exercise 9.14 Solution: HugeInteger.h2 // HugeInteger class definition.3 #ifndef HUGEINTEGER_H4 #define HUGEINTEGER_H5

cpphtp5_09_IM.fm Page 518 Thursday, December 23, 2004 4:14 PM

Page 40: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 519

6 class HugeInteger 7 {8 public:9

10 HugeInteger( long = 0 ); // conversion/default constructor11 HugeInteger( const char * ); // copy constructor1213 // addition operator; HugeInteger + HugeInteger14 HugeInteger add( const HugeInteger & );1516 // addition operator; HugeInteger + int17 HugeInteger add( int ); 1819 // addition operator; 20 // HugeInteger + string that represents large integer value21 HugeInteger add( const char * ); 2223 // subtraction operator; HugeInteger - HugeInteger24 HugeInteger subtract( const HugeInteger & ); 2526 // subtraction operator; HugeInteger - int27 HugeInteger subtract( int ); 2829 // subtraction operator; 30 // HugeInteger - string that represents large integer value31 HugeInteger subtract( const char * ); 3233 bool isEqualTo( HugeInteger & ); // is equal to34 bool isNotEqualTo( HugeInteger & ); // not equal to35 bool isGreaterThan(HugeInteger & ); // greater than36 bool isLessThan( HugeInteger & ); // less than37 bool isGreaterThanOrEqualTo( HugeInteger & ); // greater than 38 // or equal to39 bool isLessThanOrEqualTo( HugeInteger & ); // less than or equal40 bool isZero(); // is zero41 void input( const char * ); // input42 void output(); // output 43 short* getInteger(); // get integer44 private:45 short integer[ 40 ]; // 40 element array46 }; // end class HugeInteger4748 #endif

1 // Exercise 9.14 Solution: HugeInteger.cpp2 // Member-function definitions for class HugeInteger.3 #include <iostream>4 using std::cin;5 using std::cout;67 #include "HugeInteger.h" // include definiton of class HugeInteger 89 // default constructor; conversion constructor that converts

10 // a long integer into a HugeInteger object

cpphtp5_09_IM.fm Page 519 Thursday, December 23, 2004 4:14 PM

Page 41: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

520 Chapter 9 Classes: A Deeper Look, Part 1

11 HugeInteger::HugeInteger( long value )12 {13 // initialize array to zero14 for ( int i = 0; i < 40; i++ )15 integer[ i ] = 0; 1617 // place digits of argument into array 18 for ( int j = 39; value != 0 && j >= 0; j-- ) 19 {20 integer[ j ] = static_cast< short > ( value % 10 );21 value /= 10;22 } // end inner for23 } // end HugeInteger constructor2425 // copy constructor; 26 // converts a char string representing a large integer into a HugeInteger27 HugeInteger::HugeInteger( const char *string )28 {29 this->input( string ); // call input to initialize HugeInteger30 } // end HugeInteger constructor3132 // addition operator; HugeInteger + HugeInteger33 HugeInteger HugeInteger::add( const HugeInteger &op2 )34 {35 HugeInteger temp; // temporary result36 int carry = 0;3738 // iterate through HugeInteger39 for ( int i = 39; i >= 0; i-- ) 40 {41 temp.integer[ i ] = 42 integer[ i ] + op2.integer[ i ] + carry;4344 // determine whether to carry a 145 if ( temp.integer[ i ] > 9 ) 46 {47 temp.integer[ i ] %= 10; // reduce to 0-948 carry = 1;49 } // end if50 else // no carry51 carry = 0;52 } // end for5354 return temp; // return the sum55 } // end function add5657 // addition operator; HugeInteger + int58 HugeInteger HugeInteger::add( int op2 )59 { 60 // convert op2 to a HugeInteger, then invoke add61 return this->add( HugeInteger( op2 ) ); 62 } // end function add63 64 // HugeInteger + string that represents large integer value65 HugeInteger HugeInteger::add( const char *op2 )

cpphtp5_09_IM.fm Page 520 Thursday, December 23, 2004 4:14 PM

Page 42: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 521

66 { 67 // convert op2 to a HugeInteger, then invoke add68 return this->add( HugeInteger( op2 ) ); 69 } // end function add7071 // function to subtract two HugeIntegers72 HugeInteger HugeInteger::subtract( const HugeInteger &op2 )73 {74 HugeInteger temp; // temporary result75 int borrow = 0;76 77 // iterate through HugeInteger78 for ( int i = 39; i >= 0; i-- ) 79 {80 // determine to add 10 to smaller integer 81 if ( integer[i] < op2.integer[i] )82 {83 temp.integer[ i ] = 84 ( integer[ i ] + 10 ) - op2.integer[ i ] - borrow;85 borrow = 1; // set borrow to one86 } // end if87 else // if borrowing is not needed88 {89 temp.integer[ i ] = 90 integer[ i ] - op2.integer[ i ] - borrow;91 borrow = 0; // set borrow to zero92 } // end else93 } // end for9495 return temp; // return difference of two HugeIntegers96 } // end function subtract9798 // function to subtract an integer from a HugeInteger99 HugeInteger HugeInteger::subtract( int op2 )100 { 101 // convert op2 to a HugeInteger, then invoke subtract102 return this->subtract( HugeInteger( op2 ) ); 103 } // end function subtract104105 // function that takes string represeting a number106 // and subtracts it from a HugeInteger107 HugeInteger HugeInteger::subtract( const char *op2 )108 { 109 // convert op2 to a HugeInteger, then invoke subtract110 return this->subtract( HugeInteger( op2 ) ); 111 } // end function subtract112113 // function that tests if two HugeIntegers are equal114 bool HugeInteger::isEqualTo( HugeInteger &x )115 {116 return integer == x.getInteger(); 117 } // end function isEqualTo118 119 // function that tests if two HugeIntegers are not equal120 bool HugeInteger::isNotEqualTo( HugeInteger &x )

cpphtp5_09_IM.fm Page 521 Thursday, December 23, 2004 4:14 PM

Page 43: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

522 Chapter 9 Classes: A Deeper Look, Part 1

121 {122 return !( this->isEqualTo( x ) ); 123 } // end function isNotEqualTo124125 // function to test if one HugeInteger is greater than another126 bool HugeInteger::isGreaterThan( HugeInteger &x ) 127 { 128 return integer < x.getInteger(); 129 } // end function isGreaterThan130131 // function that tests if one HugeInteger is less than another132 bool HugeInteger::isLessThan( HugeInteger &x ) 133 { 134 return integer > x.getInteger(); 135 } // end function isLessThan136137 // function that tests if one HugeInteger is greater than138 // or equal to another139 bool HugeInteger::isGreaterThanOrEqualTo( HugeInteger &x )140 {141 return integer <= x.getInteger();142 } // end function isGreaterThanOrEqualTo143144 // function that tests if one HugeInteger is less than or145 // equal to another146 bool HugeInteger::isLessThanOrEqualTo( HugeInteger &x )147 {148 return integer >= x.getInteger();149 } // end function isLessThanOrEqualTo150151 // function that tests if a HugeInteger is zero152 bool HugeInteger::isZero()153 {154 return ( getInteger() == 0 );155 } // end function isZero156157 // converts a char string representing a large integer into a HugeInteger158 void HugeInteger::input( const char *string )159 {160 // initialize array to zero161 for ( int i = 0; i < 40; i++ )162 integer[ i ] = 0;163164 // place digits of argument into array165 int length = strlen( string );166167 for ( int j = 40 - length, k = 0; j < 40; j++, k++ )168169 if ( isdigit( string[ k ] ) )170 integer[ j ] = string[ k ] - '0';171 } // end function input172173 // overloaded output operator174 void HugeInteger::output()175 {

cpphtp5_09_IM.fm Page 522 Thursday, December 23, 2004 4:14 PM

Page 44: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 523

176 int i; // used for looping177178 for ( i = 0; ( integer[ i ] == 0 ) && ( i <= 39 ); i++ )179 ; // skip leading zeros180181 if ( i == 40 )182 cout << 0;183 else184 for ( ; i <= 39; i++ ) // display the HugeInteger185 cout << integer[ i ];186 187 } // end function output188 189 // return a HugeInteger190 short* HugeInteger::getInteger()191 {192 return integer;193 } // end function getInteger

1 // Exercise 9.14 Solution: Ex09_14.cpp2 // HugeInteger test program.3 #include <iostream>4 using std::cout;5 using std::endl;67 #include "HugeInteger.h" // include definiton of class HugeInteger89 int main()

10 {11 12 HugeInteger n1( 7654321 ); // HugeInteger object n113 HugeInteger n2( "7891234" ); // HugeInteger object n214 HugeInteger n3; // HugeInteger object n315 HugeInteger n4( 5 ); // HugeInteger object n416 HugeInteger n5; // HugeInteger object n5 17 18 // outputs the sum of n1 and n219 n5 = n1.add( n2 ); 20 n1.output(); 21 cout << " + "; 22 n2.output(); 23 cout << " = "; 24 n5.output();25 cout << "\n\n"; 2627 // assigns the difference of n2 and n4 to n5 then outputs n528 n5 = n2.subtract( n4 );29 n2.output();30 cout<< " - ";31 n4.output();32 cout << " = ";33 n5.output();34 cout << "\n\n";35

cpphtp5_09_IM.fm Page 523 Thursday, December 23, 2004 4:14 PM

Page 45: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

524 Chapter 9 Classes: A Deeper Look, Part 1

36 // checks for equality between n1 and n1 37 if ( n1.isEqualTo( n1 ) == true )38 { 39 n1.output(); 40 cout << " is equal ";41 n1.output(); 42 cout << "\n\n"; 43 } // end if 4445 // checks for inequality between n1 and n246 if ( n1.isNotEqualTo( n2 ) == true )47 {48 n1.output(); 49 cout << " is not equal to ";50 n2.output(); 51 cout << "\n\n"; 52 } // end if 5354 // tests for greater number between n2 and n1 55 if ( n2.isGreaterThan( n1 ) == true )56 {57 n2.output(); 58 cout << " is greater than ";59 n1.output(); 60 cout << "\n\n"; 61 } // end if 6263 // tests for smaller number between n2 and n464 if ( n2.isLessThan( n4 ) == true )65 {66 n4.output(); 67 cout << " is less than ";68 n2.output(); 69 cout << "\n\n"; 70 } // end if 71 72 // tests for smaller or equal number between n4 and n473 if ( n4.isLessThanOrEqualTo( n4 ) == true )74 {75 n4.output(); 76 cout << " is less than or equal to ";77 n4.output(); 78 cout << "\n\n"; 79 } // end if 8081 // tests for greater or equal number between n3 and n382 if ( n3.isGreaterThanOrEqualTo( n3 ) == true )83 {84 n3.output(); 85 cout << " is greater than or equal to ";86 n3.output(); 87 cout << "\n\n"; 88 } // end if 89 90 // tests for zero at n3

cpphtp5_09_IM.fm Page 524 Thursday, December 23, 2004 4:14 PM

Page 46: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 525

9.15 (TicTacToe Class) Create a class TicTacToe that will enable you to write a complete programto play the game of tic-tac-toe. The class contains as private data a 3-by-3 two-dimensional arrayof integers. The constructor should initialize the empty board to all zeros. Allow two human players.Wherever the first player moves, place a X in the specified square. Place an O wherever the secondplayer moves. Each move must be to an empty square. After each move, determine whether thegame has been won or is a draw. If you feel ambitious, modify your program so that the computermakes the moves for one of the players. Also, allow the player to specify whether he or she wants togo first or second. If you feel exceptionally ambitious, develop a program that will play three-dimen-sional tic-tac-toe on a 4-by-4-by-4 board. [Caution: This is an extremely challenging project thatcould take many weeks of effort!]

ANS:

91 if ( n3.isZero() != true )92 {93 cout << "n3 contains value ";94 n3.output();95 cout << "\n\n"; 96 } // end if statement9798 return 0;99 } // end main

7654321 + 7891234 = 15545555

7891234 - 5 = 7891229

7654321 is equal 7654321

7654321 is not equal to 7891234

5 is less than or equal to 5

0 is greater than or equal to 0

n3 contains value 0

1 // Exercise 9.15 Solution: TicTacToe.h2 #ifndef TICTACTOE_H3 #define TICTACTOE_H45 class TicTacToe 6 {7 private: 8 enum Status { WIN, DRAW, CONTINUE }; // enumeration constants9 int board[ 3 ][ 3 ];

10 public:11 TicTacToe(); // default constructor12 void makeMove(); // make move13 void printBoard(); // print board14 bool validMove( int, int ); // validate move15 bool xoMove( int ); // x o move 16 Status gameStatus(); // game status17 }; // end class TicTacToe

cpphtp5_09_IM.fm Page 525 Thursday, December 23, 2004 4:14 PM

Page 47: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

526 Chapter 9 Classes: A Deeper Look, Part 1

1819 #endif

1 // Exercise 9.15 Solution: TicTacToe.cpp2 // Member-function definitions for class TicTacToe.3 #include <iostream> 4 using std::cin; 5 using std::cout; 67 #include <iomanip> 8 using std::setw; 9

10 #include "TicTacToe.h" // include definiton of class TicTacToe1112 TicTacToe::TicTacToe()13 {14 for ( int j = 0; j < 3; j++ ) // initialize board1516 for ( int k = 0; k < 3; k++ )17 board[ j ][ k ] = ' ';18 } // end TicTacToe constructor1920 bool TicTacToe::validMove( int r, int c )21 {22 return r >= 0 && r < 3 && c >= 0 && c < 3 && board[ r ][ c ] == ' ';23 } // end function validMove2425 // must specify that type Status is part of the TicTacToe class.26 // See Chapter 24 for a discussion of namespaces.27 TicTacToe::Status TicTacToe::gameStatus()28 { 29 int a;3031 // check for a win on diagonals32 if ( board[ 0 ][ 0 ] != ' ' && board[ 0 ][ 0 ] == board[ 1 ][ 1 ] &&33 board[ 0 ][ 0 ] == board[ 2 ][ 2 ] )34 return WIN;35 else if ( board[ 2 ][ 0 ] != ' ' && board[ 2 ][ 0 ] == 36 board[ 1 ][ 1 ] && board[ 2 ][ 0 ] == board[ 0 ][ 2 ] )37 return WIN;3839 // check for win in rows40 for ( a = 0; a < 3; ++a )4142 if ( board[ a ][ 0 ] != ' ' && board[ a ][ 0 ] == 43 board[ a ][ 1 ] && board[ a ][ 0 ] == board[ a ][ 2 ] )44 return WIN;4546 // check for win in columns47 for ( a = 0; a < 3; ++a )4849 if ( board[ 0 ][ a ] != ' ' && board[ 0 ][ a ] == 50 board[ 1 ][ a ] && board[ 0 ][ a ] == board[ 2 ][ a ] )51 return WIN;

cpphtp5_09_IM.fm Page 526 Thursday, December 23, 2004 4:14 PM

Page 48: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 527

5253 // check for a completed game54 for ( int r = 0; r < 3; ++r )5556 for ( int c = 0; c < 3; ++c )5758 if ( board[ r ][ c ] == ' ' )59 return CONTINUE; // game is not finished6061 return DRAW; // game is a draw62 } // end function gameStatus6364 void TicTacToe::printBoard() 65 {66 cout << " 0 1 2\n\n";6768 for ( int r = 0; r < 3; ++r ) 69 {70 cout << r;7172 for ( int c = 0; c < 3; ++c ) 73 {74 cout << setw( 3 ) << static_cast< char > ( board[ r ][ c ] );7576 if ( c != 2 )77 cout << " |";78 } // end for7980 if ( r != 2 )81 cout << "\n ____|____|____\n | | \n";82 } // end for8384 cout << "\n\n";85 } // end function printBoard8687 void TicTacToe::makeMove()88 {89 printBoard();9091 while ( true ) 92 {93 if ( xoMove( 'X' ) )94 break;95 else if ( xoMove( 'O' ) )96 break;97 } // end while structure98 } // end function makeMove99100 bool TicTacToe::xoMove( int symbol )101 {102 int x;103 int y;104105 do 106 {

cpphtp5_09_IM.fm Page 527 Thursday, December 23, 2004 4:14 PM

Page 49: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

528 Chapter 9 Classes: A Deeper Look, Part 1

107 cout << "Player " << static_cast< char >( symbol ) 108 << " enter move: ";109 cin >> x >> y;110 cout << '\n';111 } while ( !validMove( x, y ) );112113 board[ x ][ y ] = symbol;114 printBoard();115 Status xoStatus = gameStatus();116117 if ( xoStatus == WIN ) 118 {119 cout << "Player " << static_cast< char >( symbol ) << " wins!\n";120 return true;121 } // end if122 else if ( xoStatus == DRAW ) 123 {124 cout << "Game is a draw.\n";125 return true;126 } // end else if127 else // CONTINUE128 return false; 129 } // end function xoMove

1 // Exercise 9.15 Solution: Ex09_15.cpp23 #include "TicTacToe.h" // include definiton of class TicTacToe45 int main()6 {7 TicTacToe g; // creates object g of class TicTacToe 8 g.makeMove(); // invokes function makeMove9 return 0;

10 } // end main

cpphtp5_09_IM.fm Page 528 Thursday, December 23, 2004 4:14 PM

Page 50: Classes: A Deeper Look, Part 1 - Deekle.Netdeekle.net/Jones/FallAndWinter2005-6/COP/09.pdf9 Classes: A Deeper Look, Part 1 OBJECTIVES In this chapter you will learn: How to use a preprocessor

Solutions 529

0 1 2

0 | | ____|____|____ | |1 | | ____|____|____ | |2 | |

Player X enter move: 2 0

0 1 2

0 | | ____|____|____ | |1 | | ____|____|____ | |2 X | |

Player O enter move: 2 2

0 1 2

0 | | ____|____|____ | |1 | | ____|____|____ | |2 X | | O

Player X enter move: 1 1...Player X enter move: 0 2

0 1 2

0 | | X ____|____|____ | |1 | X | O ____|____|____ | |2 X | | O

Player X wins!

cpphtp5_09_IM.fm Page 529 Thursday, December 23, 2004 4:14 PM