You are on page 1of 20

10

Classes:
A Deeper Look,
Part 2
OBJ E CTI VE S
In this chapter you will learn:
To specify const (constant) objects and const
member functions.
To create objects composed of other objects.
To use friend functions and friend classes.
To use the this pointer.
To create and destroy objects dynamically with operators
new and delete, respectively.
To use static data members and member functions.
The concept of a container class.
The notion of iterator classes that walk through the
elements of container classes.
To use proxy classes to hide implementation details from
a classs clients.
But what, to serve our
private ends,
Forbids the cheating of our
friends?
Charles Churchill
Instead of this absurd
division into sexes they ought
to class people as static and
dynamic.
Evelyn Waugh
Have no friends not equal to
yourself.
Confucius
cpphtp5_10_IM.fm Page 523 Thursday, December 23, 2004 4:14 PM
2005 Pearson Education, Inc., Upper Saddle River, NJ. All rights reserved. This material is protected under all copyright laws as they currently exist.
No portion of this material may be reproduced, in any form or by any means, without permission in writing from the publisher.

For the exclusive use of adopters of the book C++ How to Program, 5th Edition,
by Deitel and Deitel. ISBN 0-13-185757-6.
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
524 Chapter 10 Classes: A Deeper Look, Part 2
Self-Review Exercises
10.1 Fill in the blanks in each of the following:
a) must be used to initialize constant members of a class.
ANS: member initializers.
b) A nonmember function must be declared as a(n) of a class to have access
to that classs private data members.
ANS: friend.
c) The operator dynamically allocates memory for an object of a specified
type and returns a to that type.
ANS: new, pointer.
d) A constant object must be ; it cannot be modified after it is created.
ANS: initialized.
e) A(n) data member represents class-wide information.
ANS: static.
f) An objects non-static member functions have access to a self pointer to the object
called the pointer.
ANS: this.
g) The keyword specifies that an object or variable is not modifiable after it
is initialized.
ANS: const.
h) If a member initializer is not provided for a member object of a class, the object's
is called.
ANS: default constructor.
i) A member function should be declared static if it does not access class
members.
ANS: non-static.
j) Member objects are constructed their enclosing class object.
ANS: before.
k) The operator reclaims memory previously allocated by new.
ANS: delete.
10.2 Find the errors in the following class and explain how to correct them:
class Example
{
public:
Example( int y = 10 )
: data( y )
{
// empty body
} // end Example constructor
int getIncrementedData() const
{
return data++;
} // end function getIncrementedData
static int getCount()
{
cout << "Data is " << data << endl;
return count;
} // end function getCount
private:
int data;
cpphtp5_10_IM.fm Page 524 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
Exercises 525
static int count;
}; // end class Example
ANS: Error: The class definition for Example has two errors. The first occurs in function
getIncrementedData. The function is declared const, but it modifies the object.
Correction: To correct the first error, remove the const keyword from the definition
of getIncrementedData.
Error: The second error occurs in function getCount. This function is declared
static, so it is not allowed to access any non-static member of the class.
Correction: To correct the second error, remove the output line from the getCount def-
inition.
Exercises
10.3 Compare and contrast dynamic memory allocation and deallocation operators new, new [],
delete and delete [].
ANS: Operator new creates an object and dynamically allocates space in memory for that
object. Operator delete destroys a dynamically allocated object and frees the space
that was occupied by the object. Operators new [] and delete [] are used to allocate
and deallocate arrays dynamically.
10.4 Explain the notion of friendship in C++. Explain the negative aspects of friendship as de-
scribed in the text.
ANS: Functions that are declared as friends of a class have access to that classs private
and protected members. Some people in the object-oriented programming commu-
nity prefer not to use friend functions. Such people believe friendship corrupts in-
formation hiding and weakens the value of the object-oriented design approach,
because friend functions can directly access a classs implementation details that are
supposed to be hidden.
10.5 Can a correct Time class definition include both of the following constructors? If not, ex-
plain why not.
Time( int h = 0, int m = 0, int s = 0 );
Time();
ANS: No. There is ambiguity between the two constructors. When a call is made to the de-
fault constructor, the compiler cannot determine which one to use because both con-
structors can be called with no arguments.
10.6 What happens when a return type, even void, is specified for a constructor or destructor?
ANS: A compilation error occurs. A programmer cannot specify a return type for a con-
structor or destructor.
10.7 Modify class Date in Fig. 10.10 to have the following capabilities:
a) Output the date in multiple formats such as
DDD YYYY
MM/DD/YY
June 14, 1992
b) Use overloaded constructors to create Date objects initialized with dates of the formats
in part (a).
cpphtp5_10_IM.fm Page 525 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
526 Chapter 10 Classes: A Deeper Look, Part 2
c) Create a Date constructor that reads the system date using the standard library functions
of the <ctime> header and sets the Date members. (See your compilers reference docu-
mentation or www.cplusplus.com/ref/ctime/index.html for information on the func-
tions in header <ctime>.)
In Chapter 11, we will be able to create operators for testing the equality of two dates and for com-
paring dates to determine whether one date is prior to, or after, another.
ANS:
1 // Exercise 10.7 Solution: Date.h
2 // Date class definition; Member functions defined in Date.cpp
3 #ifndef DATE_H
4 #define DATE_H
5
6 #include <string>
7 using std::string;
8
9 class Date
10 {
11 public:
12 Date(); // default constructor uses <ctime> functions to set date
13 Date( int, int ); // constructor using ddd yyyy format
14 Date( int, int, int ); // constructor using dd/mm/yy format
15 Date( string, int, int ); // constructor using Month dd, yyyy format
16 void setDay( int ); // set the day
17 void setMonth( int ); // set the month
18 void print() const; // print date in month/day/year format
19 void printDDDYYYY() const; // print date in ddd yyyy format
20 void printMMDDYY() const; // print date in mm/dd/yy format
21 void printMonthDDYYYY() const; // print date in Month dd, yyyy format
22 ~Date(); // provided to confirm destruction order
23 private:
24 int month; // 1-12 (January-December)
25 int day; // 1-31 based on month
26 int year; // any year
27
28 // utility functions
29 int checkDay( int ) const; // check if day is proper for month and year
30 int daysInMonth( int ) const; // returns number of days in given month
31 bool isLeapYear() const; // indicates whether date is in a leap year
32 int convertDDToDDD() const; // get 3-digit day based on month and day
33 void setMMDDFromDDD( int ); // set month and day based on 3-digit day
34 string convertMMToMonth( int ) const; // convert mm to month name
35 void setMMFromMonth( string ); // convert month name to mm
36 int convertYYYYToYY() const; // get 2-digit year based on 4-digit year
37 void setYYYYFromYY( int ); // set year based on 2-digit year
38 }; // end class Date
39
40 #endif
1 // Exercise 10.7 Solution: Date.cpp
2 // Member-function definitions for class Date.
3 #include <iostream>
cpphtp5_10_IM.fm Page 526 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
Exercises 527
4 using std::cout;
5 using std::endl;
6
7 #include <iomanip>
8 using std::setw;
9 using std::setfill;
10
11 #include <ctime>
12 using std::time;
13 using std::localtime;
14 using std::tm;
15 using std::time_t;
16
17 #include "Date.h" // include Date class definition
18
19 // default constructor that sets date using <ctime> functions
20 Date::Date()
21 {
22 // pointer of type struct tm which holds calendar time components
23 struct tm *ptr;
24
25 time_t t = time( 0 ); // determine current calendar time
26
27 // convert current calendar time pointed to by t into
28 // broken down time and assign it to ptr
29 ptr = localtime( &t );
30
31 day = ptr->tm_mday; // broken down day of month
32 month = 1 + ptr->tm_mon; // broken down month since January
33 year = ptr->tm_year + 1900; // broken down year since 1900
34 } // end Date constructor
35
36 // constructor that takes date in ddd yyyy format
37 Date::Date( int ddd, int yyyy )
38 {
39 year = yyyy; // could validate
40 setMMDDFromDDD( ddd ); // set month and day based on ddd
41 } // end Date constructor
42
43 // constructor that takes date in mm/dd/yy format
44 Date::Date( int mm, int dd, int yy )
45 {
46 setYYYYFromYY( yy ); // set 4-digit year based on yy
47 setMonth( mm ); // validate and set the month
48 setDay( dd ); // validate and set the day
49 } // end Date constructor
50
51 // constructor that takes date in Month dd, yyyy format
52 Date::Date( string monthName, int dd, int yyyy )
53 {
54 setMMFromMonth( monthName ); // set month based on month name
55 setDay( dd ); // validate and set the day
56 year = yyyy; // could validate
57 } // end Date constructor
58
cpphtp5_10_IM.fm Page 527 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
528 Chapter 10 Classes: A Deeper Look, Part 2
59 // validate and store the day
60 void Date::setDay( int d )
61 {
62 day = checkDay( d ); // validate the day
63 } // end function setDay
64
65 // validate and store the month
66 void Date::setMonth( int m )
67 {
68 if ( m > 0 && m <= 12 ) // validate the month
69 month = m;
70 else
71 {
72 month = 1; // invalid month set to 1
73 cout << "Invalid month (" << m << ") set to 1.\n";
74 } // end else
75 } // end function setMonth
76
77 // print Date object in form: month/day/year
78 void Date::print() const
79 {
80 cout << month << '/' << day << '/' << year << endl;
81 } // end function print
82
83 // print Date object in form: ddd yyyy
84 void Date::printDDDYYYY() const
85 {
86 cout << convertDDToDDD() << ' ' << year << endl;
87 } // end function printDDDYYYY
88
89 // print Date object in form: mm/dd/yy
90 void Date::printMMDDYY() const
91 {
92 cout << setw( 2 ) << setfill( '0' ) << month << '/'
93 << setw( 2 ) << setfill( '0' ) << day << '/'
94 << setw( 2 ) << setfill( '0' ) << convertYYYYToYY() << endl;
95 } // end function printMMDDYY
96
97 // print Date object in form: Month dd, yyyy
98 void Date::printMonthDDYYYY() const
99 {
100 cout << convertMMToMonth( month ) << ' ' << day << ", " << year
101 << endl;
102 } // end function printMonthDDYYYY
103
104 // output Date object to show when its destructor is called
105 Date::~Date()
106 {
107 cout << "Date object destructor for date ";
108 print();
109 cout << endl;
110 } // end ~Date destructor
111
112 // utility function to confirm proper day value based on
113 // month and year; handles leap years, too
cpphtp5_10_IM.fm Page 528 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
Exercises 529
114 int Date::checkDay( int testDay ) const
115 {
116 // determine whether testDay is valid for specified month
117 if ( testDay > 0 && testDay <= daysInMonth( month ) )
118 return testDay;
119
120 // February 29 check for leap year
121 if ( month == 2 && testDay == 29 && isLeapYear() )
122 return testDay;
123
124 cout << "Invalid day (" << testDay << ") set to 1.\n";
125 return 1; // leave object in consistent state if bad value
126 } // end function checkDay
127
128 // return the number of days in a month
129 int Date::daysInMonth( int m ) const
130 {
131 if ( isLeapYear() && m == 2 )
132 return 29;
133
134 static const int daysPerMonth[ 13 ] =
135 { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
136
137 return daysPerMonth[ m ];
138 } // end function daysInMonth
139
140 // test for a leap year
141 bool Date::isLeapYear() const
142 {
143 if ( year % 400 == 0 || ( year % 4 == 0 && year % 100 != 0 ) )
144 return true;
145 else
146 return false;
147 } // end function isLeapYear
148
149 // calculate 3-digit day based on Date object's current month and day
150 int Date::convertDDToDDD() const
151 {
152 int ddd = 0;
153
154 // for each month that has passed, add days to ddd
155 for ( int i = 1; i < month; i++ )
156 ddd += daysInMonth( i );
157
158 // add days from current month
159 ddd += day;
160
161 return ddd;
162 } // end function convertDDToDDD
163
164 // set month and day based on 3-digit day
165 void Date::setMMDDFromDDD( int ddd )
166 {
167 int dayTotal = 0;
168 int m;
cpphtp5_10_IM.fm Page 529 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
530 Chapter 10 Classes: A Deeper Look, Part 2
169
170 for ( m = 1; m <= 12 && ( dayTotal + daysInMonth( m ) ) < ddd; m++ )
171 dayTotal += daysInMonth( m );
172
173 setMonth( m );
174 setDay( ddd - dayTotal );
175 } // end function setMMDDFromDDD
176
177 // utility function to convert month number to month name
178 string Date::convertMMToMonth( int mm ) const
179 {
180 static const string months[] =
181 { "", "January", "February", "March", "April", "May", "June",
182 "July", "August", "September", "October", "November", "December" };
183
184 return months[ mm ];
185 } // end function convertMMToMonth
186
187 // set month number based on month name
188 void Date::setMMFromMonth( string m )
189 {
190 bool matchFound = false;
191
192 // loop for each month, checking for a match
193 for ( int i = 1; i <= 12 && !matchFound; i++ )
194 {
195 string tempMonth = convertMMToMonth( i );
196
197 if ( tempMonth == m )
198 {
199 setMonth( i );
200 matchFound = true;
201 } // end if
202 } // end for
203
204 if ( !matchFound )
205 {
206 cout << "Invalid month name (" << month << "). month set to 1.\n";
207 setMonth( 1 ); // leave object in consistent state if bad value
208 } // end if
209 } // end function setMMFromMonth
210
211 // utility function to convert 4-digit year to 2-digit year
212 int Date::convertYYYYToYY() const
213 {
214 // if year is in 2000s, subtract 2000
215 // else, assume year is in the 1900s and subtract 1900
216 return ( year >= 2000 ? year - 2000 : year - 1900 );
217 } // end function convertYYYYtoYY
218
219 // utility function to convert 2-digit year to 4-digit year
220 void Date::setYYYYFromYY( int yy )
221 {
222 // if yy is less than 7, assume its in the 2000s
223 // if yy is greater than or equal to 7, assume it's in the 1900s
cpphtp5_10_IM.fm Page 530 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
Exercises 531
224 year = ( yy < 7 ? yy + 2000 : yy + 1900 );
225 } // end function setYYYYFromYY
1 // Exercise 10.7 Solution: ex10_07.cpp
2 // Driver program for class Date.
3 #include <iostream>
4 using std::cout;
5 using std::endl;
6
7 #include "Date.h" // include Date class definition
8
9 int main()
10 {
11 Date date1( 256, 1999 ); // initialize using ddd yyyy format
12 Date date2( 3, 25, 04 ); // initialize using mm/dd/yy format
13 Date date3( "September", 1, 2000 ); // "month" dd, yyyy format
14 Date date4; // initialize to current date with default constructor
15
16 // print Date objects in default format
17 date1.print();
18 date2.print();
19 date3.print();
20 date4.print();
21 cout << '\n';
22
23 // print Date objects in 'ddd yyyy' format
24 date1.printDDDYYYY();
25 date2.printDDDYYYY();
26 date3.printDDDYYYY();
27 date4.printDDDYYYY();
28 cout << '\n';
29
30 // print Date objects in 'mm/dd/yy' format
31 date1.printMMDDYY();
32 date2.printMMDDYY();
33 date3.printMMDDYY();
34 date4.printMMDDYY();
35 cout << '\n';
36
37 // print Date objects in '"month" d, yyyy' format
38 date1.printMonthDDYYYY();
39 date2.printMonthDDYYYY();
40 date3.printMonthDDYYYY();
41 date4.printMonthDDYYYY();
42 cout << endl;
43
44 return 0;
45 } // end main
cpphtp5_10_IM.fm Page 531 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
532 Chapter 10 Classes: A Deeper Look, Part 2
10.8 Create a SavingsAccount class. Use a static data member annualInterestRate to store the
annual interest rate for each of the savers. Each member of the class contains a private data member
savingsBalance indicating the amount the saver currently has on deposit. Provide member func-
tion calculateMonthlyInterest that calculates the monthly interest by multiplying the balance by
annualInterestRate divided by 12; this interest should be added to savingsBalance. Provide a
static member function modifyInterestRate that sets the static annualInterestRate to a new
value. Write a driver program to test class SavingsAccount. Instantiate two different objects of class
SavingsAccount, saver1 and saver2, with balances of $2000.00 and $3000.00, respectively. Set the
annualInterestRate to 3 percent. Then calculate the monthly interest and print the new balances
for each of the savers. Then set the annualInterestRate to 4 percent, calculate the next months
interest and print the new balances for each of the savers.
ANS:
9/13/1999
3/25/2004
9/1/2000
12/14/2004
256 1999
85 2004
245 2000
349 2004
09/13/99
03/25/04
09/01/00
12/14/04
September 13, 1999
March 25, 2004
September 1, 2000
December 14, 2004
Date object destructor for date 12/14/2004
Date object destructor for date 9/1/2000
Date object destructor for date 3/25/2004
Date object destructor for date 9/13/1999
1 // SavingsAccount.h
2 // Header file for class SavingsAccount.
3 #ifndef SAVINGS_ACCOUNT_H
4 #define SAVINGS_ACCOUNT_H
5
6 class SavingsAccount
7 {
8 public:
9 // constructor sets balance to value greater than or equal to zero
10 SavingsAccount( double b )
11 {
12 savingsBalance = ( b >= 0.0 ? b : 0.0 );
cpphtp5_10_IM.fm Page 532 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
Exercises 533
13 } // end SavingsAccount constructor
14
15 void calculateMonthlyInterest(); // calculate interest; add to balance
16 static void modifyInterestRate( double );
17 void printBalance() const;
18 private:
19 double savingsBalance; // the account balance
20 static double annualInterestRate; // the interest rate of all accounts
21 }; // end class SavingsAccount
22
23 #endif
1 // Exercise 10.8 Solution: SavingsAccount.cpp
2 // Member-function defintions for class SavingsAccount.
3 #include <iostream>
4 using std::cout;
5 using std::fixed;
6
7 #include <iomanip>
8 using std::setprecision;
9
10 #include "SavingsAccount.h" // SavingsAccount class definition
11
12 // initialize static data member
13 double SavingsAccount::annualInterestRate = 0.0;
14
15 // calculate monthly interest for this savings account
16 void SavingsAccount::calculateMonthlyInterest()
17 {
18 savingsBalance += savingsBalance * ( annualInterestRate / 12.0 );
19 } // end function calculateMonthlyInterest
20
21 // function for modifying static member variable annualInterestRate
22 void SavingsAccount::modifyInterestRate( double i )
23 {
24 annualInterestRate = ( i >= 0.0 && i <= 1.0 ) ? i : 0.03;
25 } // end function modifyInterestRate
26
27 // prints balance of the savings account
28 void SavingsAccount::printBalance() const
29 {
30 cout << fixed << '$' << setprecision( 2 ) << savingsBalance;
31 } // end function printBalance
1 // Exercise 10.8 Solution: ex10_08.cpp
2 // Driver program for class SavingsAccount.
3 #include <iostream>
4 using std::cout;
5 using std::endl;
6
7 #include <iomanip>
8 using std::setw;
9
cpphtp5_10_IM.fm Page 533 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
534 Chapter 10 Classes: A Deeper Look, Part 2
10.9 Create class IntegerSet for which each object can hold integers in the range 0 through 100.
A set is represented internally as an array of ones and zeros. Array element a[ i ] is 1 if integer i is
in the set. Array element a[ j ] is 0 if integer j is not in the set. The default constructor initializes
a set to the so-called empty set, i.e., a set whose array representation contains all zeros.
Provide member functions for the common set operations. For example, provide a unionOfSets
member function that creates a third set that is the set-theoretic union of two existing sets (i.e., an
element of the third sets array is set to 1 if that element is 1 in either or both of the existing sets, and
an element of the third sets array is set to 0 if that element is 0 in each of the existing sets).
10 #include "SavingsAccount.h" // SavingsAccount class definition
11
12 int main()
13 {
14 SavingsAccount saver1( 2000.0 );
15 SavingsAccount saver2( 3000.0 );
16
17 SavingsAccount::modifyInterestRate( .03 ); // change interest rate
18
19 cout << "Initial balances:\nSaver 1: ";
20 saver1.printBalance();
21 cout << "\tSaver 2: ";
22 saver2.printBalance();
23
24 saver1.calculateMonthlyInterest();
25 saver2.calculateMonthlyInterest();
26
27 cout << "\n\nBalances after 1 month's interest applied at .03:\n"
28 << "Saver 1: ";
29 saver1.printBalance();
30 cout << "\tSaver 2: ";
31 saver2.printBalance();
32
33 SavingsAccount::modifyInterestRate( .04 ); // change interest rate
34 saver1.calculateMonthlyInterest();
35 saver2.calculateMonthlyInterest();
36
37 cout << "\n\nBalances after 1 month's interest applied at .04:\n"
38 << "Saver 1: ";
39 saver1.printBalance();
40 cout << "\tSaver 2: ";
41 saver2.printBalance();
42 cout << endl;
43 return 0;
44 } // end main
Initial balances:
Saver 1: $2000.00 Saver 2: $3000.00
Balances after 1 month's interest applied at .03:
Saver 1: $2005.00 Saver 2: $3007.50
Balances after 1 month's interest applied at .04:
Saver 1: $2011.68 Saver 2: $3017.53
cpphtp5_10_IM.fm Page 534 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
Exercises 535
Provide an intersectionOfSets member function which creates a third set which is the set-
theoretic intersection of two existing sets (i.e., an element of the third sets array is set to 0 if that
element is 0 in either or both of the existing sets, and an element of the third sets array is set to 1 if
that element is 1 in each of the existing sets).
Provide an insertElement member function that inserts a new integer k into a set (by setting
a[ k ] to 1). Provide a deleteElement member function that deletes integer m (by setting a[ m ]
to 0).
Provide a printSet member function that prints a set as a list of numbers separated by spaces.
Print only those elements that are present in the set (i.e., their position in the array has a value of
1). Print --- for an empty set.
Provide an isEqualTo member function that determines whether two sets are equal.
Provide an additional constructor that receives an array of integers and the size of that array
and uses the array to initialize a set object.
Now write a driver program to test your IntegerSet class. Instantiate several IntegerSet
objects. Test that all your member functions work properly.
ANS:
1 // Exercise 10.9 Solution: IntegerSet.h
2 // Header file for class IntegerSet
3 #ifndef INTEGER_SET_H
4 #define INTEGER_SET_H
5
6 class IntegerSet
7 {
8 public:
9 // default constructor
10 IntegerSet()
11 {
12 emptySet(); // set all elements of set to 0
13 } // end IntegerSet constructor
14
15 IntegerSet( int [], int ); // constructor that takes an initial set
16 IntegerSet unionOfSets( const IntegerSet& );
17 IntegerSet intersectionOfSets( const IntegerSet& );
18 void emptySet(); // set all elements of set to 0
19 void inputSet(); // read values from user
20 void insertElement( int );
21 void deleteElement( int );
22 void printSet() const;
23 bool isEqualTo( const IntegerSet& ) const;
24 private:
25 int set[ 101 ]; // range of 0 - 100
26
27 // determines a valid entry to the set
28 int validEntry( int x ) const
29 {
30 return ( x >= 0 && x <= 100 );
31 } // end function validEntry
32 }; // end class IntegerSet
33
34 #endif
cpphtp5_10_IM.fm Page 535 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
536 Chapter 10 Classes: A Deeper Look, Part 2
1 // Exercise 10.9 Solution: IntegerSet.cpp
2 // Member-function definitions for class IntegerSet.
3 #include <iostream>
4 using std::cout;
5 using std::cin;
6 using std::cerr;
7
8 #include <iomanip>
9 using std::setw;
10
11 #include "IntegerSet.h" // IntegerSet class definition
12
13 // constructor creates a set from array of integers
14 IntegerSet::IntegerSet( int array[], int size)
15 {
16 emptySet();
17
18 for ( int i = 0; i < size; i++ )
19 insertElement( array[ i ] );
20 } // end IntegerSet constructor
21
22 // initializes a set to the empty set
23 void IntegerSet::emptySet()
24 {
25 for ( int y = 0; y < 101; y++ )
26 set[ y ] = 0;
27 } // end function emptySet
28
29 // input a set from the user
30 void IntegerSet::inputSet()
31 {
32 int number;
33
34 do
35 {
36 cout << "Enter an element (-1 to end): ";
37 cin >> number;
38
39 if ( validEntry( number ) )
40 set[ number ] = 1;
41 else if ( number != -1 )
42 cerr << "Invalid Element\n";
43 } while ( number != -1 ); // end do...while
44
45 cout << "Entry complete\n";
46 } // end function inputSet
47
48 // prints the set to the output stream
49 void IntegerSet::printSet() const
50 {
51 int x = 1;
52 bool empty = true; // assume set is empty
53
54 cout << '{';
55
cpphtp5_10_IM.fm Page 536 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
Exercises 537
56 for (int u = 0; u < 101; u++ )
57 {
58 if ( set[ u ] )
59 {
60 cout << setw( 4 ) << u << ( x % 10 == 0 ? "\n" : "" );
61 empty = false; // set is not empty
62 x++;
63 } // end if
64 } // end for
65
66 if ( empty )
67 cout << setw( 4 ) << "---"; // display an empty set
68
69 cout << setw( 4 ) << "}" << '\n';
70 } // end function printSet
71
72 // returns the union of two sets
73 IntegerSet IntegerSet::unionOfSets( const IntegerSet &r )
74 {
75 IntegerSet temp;
76
77 // if element is in either set, add to temporary set
78 for ( int n = 0; n < 101; n++ )
79 if ( set[ n ] == 1 || r.set[ n ] == 1 )
80 temp.set[ n ] = 1;
81
82 return temp;
83 } // end function unionOfSets
84
85 // returns the intersection of two sets
86 IntegerSet IntegerSet::intersectionOfSets( const IntegerSet &r )
87 {
88 IntegerSet temp;
89
90 // if element is in both sets, add to temporary set
91 for ( int w = 0; w < 101; w++ )
92 if ( set[ w ] == 1 && r.set[ w ] == 1 )
93 temp.set[ w ] = 1;
94
95 return temp;
96 } // end function intersectionOfSets
97
98 // insert a new integer into this set
99 void IntegerSet::insertElement( int k )
100 {
101 if ( validEntry( k ) )
102 set[ k ] = 1;
103 else
104 cerr << "Invalid insert attempted!\n";
105 } // end function insertElement
106
107 // removes an integer from this set
108 void IntegerSet::deleteElement( int m )
109 {
110 if ( validEntry( m ) )
cpphtp5_10_IM.fm Page 537 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
538 Chapter 10 Classes: A Deeper Look, Part 2
111 set[ m ] = 0;
112 else
113 cerr << "Invalid delete attempted!\n";
114 } // end function deleteElement
115
116 // determines if two sets are equal
117 bool IntegerSet::isEqualTo( const IntegerSet &r ) const
118 {
119 for ( int v = 0; v < 101; v++ )
120 if ( set[ v ] != r.set[ v ] )
121 return false; // sets are not-equal
122
123 return true; // sets are equal
124 } // end function isEqualTo
1 // Exercise 10.9 Solution: ex10_09.cpp
2 // Driver program for class IntegerSet.
3 #include <iostream>
4 using std::cout;
5 using std::endl;
6
7 #include "IntegerSet.h" // IntegerSet class definition
8
9 int main()
10 {
11 IntegerSet a;
12 IntegerSet b;
13 IntegerSet c;
14 IntegerSet d;
15
16 cout << "Enter set A:\n";
17 a.inputSet();
18 cout << "\nEnter set B:\n";
19 b.inputSet();
20 c = a.unionOfSets( b );
21 d = a.intersectionOfSets( b );
22 cout << "\nUnion of A and B is:\n";
23 c.printSet();
24 cout << "Intersection of A and B is:\n";
25 d.printSet();
26
27 if ( a.isEqualTo( b ) )
28 cout << "Set A is equal to set B\n";
29 else
30 cout << "Set A is not equal to set B\n";
31
32 cout << "\nInserting 77 into set A...\n";
33 a.insertElement( 77 );
34 cout << "Set A is now:\n";
35 a.printSet();
36
37 cout << "\nDeleting 77 from set A...\n";
38 a.deleteElement( 77 );
39 cout << "Set A is now:\n";
cpphtp5_10_IM.fm Page 538 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
Exercises 539
10.10 It would be perfectly reasonable for the Time class of Figs. 10.1810.19 to represent the
time internally as the number of seconds since midnight rather than the three integer values hour,
minute and second. Clients could use the same public methods and get the same results. Modify
40 a.printSet();
41
42 const int arraySize = 10;
43 int intArray[ arraySize ] = { 25, 67, 2, 9, 99, 105, 45, -5, 100, 1 };
44 IntegerSet e( intArray, arraySize );
45
46 cout << "\nSet e is:\n";
47 e.printSet();
48
49 cout << endl;
50
51 return 0;
52 } // end main
Enter set A:
Enter an element (-1 to end): 45
Enter an element (-1 to end): 76
Enter an element (-1 to end): 34
Enter an element (-1 to end): 6
Enter an element (-1 to end): -1
Entry complete
Enter set B:
Enter an element (-1 to end): 34
Enter an element (-1 to end): 8
Enter an element (-1 to end): 93
Enter an element (-1 to end): 45
Enter an element (-1 to end): -1
Entry complete
Union of A and B is:
{ 6 8 34 45 76 93 }
Intersection of A and B is:
{ 34 45 }
Set A is not equal to set B
Inserting 77 into set A...
Set A is now:
{ 6 34 45 76 77 }
Deleting 77 from set A...
Set A is now:
{ 6 34 45 76 }
Invalid insert attempted!
Invalid insert attempted!
Set e is:
{ 1 2 9 25 45 67 99 100 }
cpphtp5_10_IM.fm Page 539 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
540 Chapter 10 Classes: A Deeper Look, Part 2
the Time class of Fig. 10.18 to implement the time as the number of seconds since midnight and
show that there is no visible change in functionality to the clients of the class. [Note: This exercise
nicely demonstrates the virtues of implementation hiding.]
ANS:
1 // Exercise 10.10 Solution: Time.h
2 // Time class definition; Member functions defined in Time.cpp.
3 #ifndef TIME_H
4 #define TIME_H
5
6 class Time
7 {
8 public:
9 Time( int = 0, int = 0, int = 0 ); // default constructor
10
11 // set functions (the Time & return types enable cascading)
12 Time &setTime( int, int, int ); // set hour, minute, second
13 Time &setHour( int ); // set hour
14 Time &setMinute( int ); // set minute
15 Time &setSecond( int ); // set second
16
17 // get functions (normally declared const)
18 int getHour() const; // return hour
19 int getMinute() const; // return minute
20 int getSecond() const; // return second
21
22 // print functions (normally declared const)
23 void printUniversal() const; // print universal time
24 void printStandard() const; // print standard time
25 private:
26 int totalSeconds; // number of seconds since midnight
27 }; // end class Time
28
29 #endif
1 // Exercise 10.10 Solution: Time.cpp
2 // Member-function definitions for Time class.
3 #include <iostream>
4 using std::cout;
5
6 #include <iomanip>
7 using std::setfill;
8 using std::setw;
9
10 #include "Time.h" // Time class definition
11
12 // constructor function to initialize private data;
13 // calls member function setTime to set variables;
14 // default values are 0 (see class definition)
15 Time::Time( int hr, int min, int sec )
16 {
17 setTime( hr, min, sec );
18 } // end Time constructor
cpphtp5_10_IM.fm Page 540 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
Exercises 541
19
20 // set values of hour, minute, and second
21 Time &Time::setTime( int h, int m, int s ) // note Time & return
22 {
23 setHour( h );
24 setMinute( m );
25 setSecond( s );
26 return *this; // enables cascading
27 } // end function setTime
28
29 // set hour value
30 Time &Time::setHour( int h ) // note Time & return
31 {
32 int hours = ( h >= 0 && h < 24 ) ? h : 0;
33 totalSeconds = ( hours * 3600 ) + ( getMinute() * 60 ) + getSecond();
34 return *this; // enables cascading
35 } // end function setHour
36
37 // set minute value
38 Time &Time::setMinute( int m ) // note Time & return
39 {
40 int minutes = ( m >= 0 && m < 60 ) ? m : 0;
41 totalSeconds = ( getHour() * 3600 ) + ( minutes * 60 ) + getSecond();
42 return *this; // enables cascading
43 } // end function setMinute
44
45 // set second value
46 Time &Time::setSecond( int s ) // note Time & return
47 {
48 int seconds = ( s >= 0 && s < 60 ) ? s : 0;
49 totalSeconds = ( getHour() * 3600 ) + ( getMinute() * 60 ) + seconds;
50 return *this; // enables cascading
51 } // end function setSecond
52
53 // get hour value
54 int Time::getHour() const
55 {
56 return ( totalSeconds / 3600 );
57 } // end function getHour
58
59 // get minute value
60 int Time::getMinute() const
61 {
62 return ( ( totalSeconds % 3600 ) / 60 );
63 } // end function getMinute
64
65 // get second value
66 int Time::getSecond() const
67 {
68 return ( ( totalSeconds % 3600 ) % 60 );
69 } // end function getSecond
70
71 // print Time in universal-time format (HH:MM:SS)
72 void Time::printUniversal() const
73 {
cpphtp5_10_IM.fm Page 541 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.
542 Chapter 10 Classes: A Deeper Look, Part 2
74 cout << setfill( '0' ) << setw( 2 ) << getHour() << ":"
75 << setw( 2 ) << getMinute() << ":" << setw( 2 ) << getSecond();
76 } // end function printUniversal
77
78 // print Time in standard-time format (HH:MM:SS AM or PM)
79 void Time::printStandard() const
80 {
81 int hour = getHour();
82 cout << ( ( hour == 0 || hour == 12 ) ? 12 : hour % 12 )
83 << ":" << setfill( '0' ) << setw( 2 ) << getMinute()
84 << ":" << setw( 2 ) << getSecond() << ( hour < 12 ? " AM" : " PM" );
85 } // end function printStandard
1 // Exercise 10.10 Solution: ex10_10.cpp
2 // Driver program for Time class.
3 #include <iostream>
4 using std::cout;
5 using std::endl;
6
7 #include "Time.h" // Time class definition
8
9 int main()
10 {
11 Time t; // create Time object
12
13 // cascaded function calls
14 t.setHour( 18 ).setMinute( 30 ).setSecond( 22 );
15
16 // output time in universal and standard formats
17 cout << "Universal time: ";
18 t.printUniversal();
19
20 cout << "\nStandard time: ";
21 t.printStandard();
22
23 cout << "\n\nNew standard time: ";
24
25 // cascaded function calls
26 t.setTime( 20, 20, 20 ).printStandard();
27 cout << endl;
28 return 0;
29 } // end main
Universal time: 18:30:22
Standard time: 6:30:22 PM
New standard time: 8:20:20 PM
cpphtp5_10_IM.fm Page 542 Thursday, December 23, 2004 4:14 PM
Copyright 1992-2005 by Deitel & Associates, Inc. All Rights Reserved.