The program of Figs. 10.6–10.8 demonstrates a Date
class, which uses overloaded prefix and postfix increment operators to add 1 to the day in a Date
object, while causing appropriate increments to the month and year if necessary. The Date
header (Fig. 10.6) specifies that Date
’s public
interface includes an overloaded stream insertion operator (line 10), a default constructor (line 12), a setDate
function (line 13), an overloaded prefix increment operator (line 14), an overloaded postfix increment operator (line 15), an overloaded +=
addition assignment operator (line 16), a function to test for leap years (line 17) and a function to determine whether a day is the last day of the month (line 18).
Function main
(Fig. 10.8) creates two Date
objects (lines 8–9)—d1
is initialized to December 27, 2010 and d2
is initialized by default to January 1, 1900. The Date
constructor (defined in Fig. 10.7, lines 13–15) calls setDate
(defined in Fig. 10.7, lines 18–42) to validate the month, day and year specified. Invalid values for the month, day or year result in invalid_argument
exceptions.
Line 11 of main
(Fig. 10.8) outputs each Date
object, using the overloaded stream insertion operator (defined in Fig. 10.7, lines 105–111). Line 12 of main
uses the overloaded operator +=
(defined in Fig. 10.7, lines 61–67) to add seven days to d1
. Line 14 in Fig. 10.8 uses function setDate
to set d2
to February 28, 2008, which is a leap year. Then, line 16 preincrements d2
to show that the date increments properly to February 29. Next, line 18 creates a Date
object, d3
, which is initialized with the date July 13, 2010. Then line 22 increments d3
by 1 with the overloaded prefix increment operator. Lines 20–23 output d3
before and after the preincrement operation to confirm that it worked correctly. Finally, line 27 increments d3
with the overloaded postfix increment operator. Lines 25–28 output d3
before and after the postincrement operation to confirm that it worked correctly.
Date
Class Prefix Increment OperatorOverloading the prefix increment operator is straightforward. The prefix increment operator (defined in Fig. 10.7, lines 45–48) calls utility function helpIncrement
(defined in lines 86–102) to increment the date. This function deals with “wraparounds” or “carries” that occur when we increment past a month’s last day, which requires incrementing the month. If the month is already 12, then the year must also be incremented and the month must be set to 1. Function helpIncrement
uses function endOfMonth
to determine whether the end of a month has been reached and increment the day correctly.
The overloaded prefix increment operator returns a reference to the current Date
object (i.e., the one that was just incremented). This occurs because the current object, *this
, is returned as a Date&
. This enables a preincremented Date
object to be used as an lvalue, which is how the built-in prefix increment operator works for fundamental types.
Date
Class Postfix Increment OperatorOverloading the postfix increment operator (defined in Fig. 10.7, lines 52–58) is trickier. To emulate the effect of the postincrement, we must return an unincremented copy of the Date
object. For example, if int
variable x
has the value 7
, the statement
cout << x++ << endl;
outputs the original value of x
. We’d like our postfix increment operator to operate the same way on a Date
object. On entry to operator++
, we save the current object (*this
) in temp
(line 53). Next, we call helpIncrement
to increment the current Date
object. Then, line 57 returns temp
—the unincremented copy of the original Date
object. This function cannot return a reference to the local Date
object temp
, because a local variable is destroyed when the function in which it’s declared exits. Thus, declaring the return type to this function as Date&
would return a reference to an object that no longer exists.