As it is currently defined, the Date class does not permit any access to its individual month, day, and year components. For example, you cannot read or modify the month value of a Date object. To remedy this, you can revise the Date class as follows:
class Date
{
public:
Date( int mn, int dy, int yr ); // Constructor
// Member functions:
int getMonth(); // Get month
int getDay(); // Get day
int getYear(); // Get year
void setMonth( int mn ); // Set month
void setDay( int dy ); // Set day
void setYear( int yr ); // Set year
void display(); // Print date
~Date(); // Destructor
private:
int month, day, year; // Private data members
};
This version of Date includes member functions to read and modify the month, day, and year members. The function definitions are as follows:
inline int Date::getMonth()
{
return month;
}
inline int Date::getDay()
{
return day;
}
inline int Date::getYear()
{
return year;
}
void Date::setMonth( int mn )
{
month = max( 1, mn );
month = min( month, 12 );
}
void Date::setDay( int dy )
{
static int length[] = { 0, 31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31 };
day = max( 1, dy );
day = min( day, length[month] );
}
void Date::setYear( int yr )
{
year = max( 1, yr );
}
The various get functions simply return the value of the appropriate data member. However, the set functions do not simply assign a new value to a data member. These functions also check the validity of the specified value before assigning it. This is another way to ensure that Date objects contain valid values.
The following example uses these new member functions:
void main()
{
int i;
Date deadline( 3, 10, 1980 );
i = deadline.getMonth(); // Read month value
deadline.setMonth( 4 ); // Modify month value
deadline.setMonth( deadline.getMonth() + 1 ); // Increment
}
Notice that the get functions are declared inline because they're so short. Because those functions have no function call overhead, calling them is as efficient as directly accessing public data members.
Member functions can also be declared inline without using the inline keyword. Instead, you can place the body of the function inside the class declaration, as follows:
class Date
{
public:
Date( int mn, int dy, int yr );
int getMonth() { return month; } // Inline member functions
int getDay() { return day; }
int getYear() { return year; }
// etc....
};
This style of declaration has precisely the same effect as using the inline keyword with separate function definitions. You can use whichever style you find more readable.
Now that the class has member functions to set its values, you can change the way a Date object is constructed. You can overload constructors in the same way you overload other functions. The following example defines two versions of Date's constructor, one that takes parameters and one that doesn't:
class Date
{
public:
Date(); // Constructor with no parameters
Date( int mn, int dy, int yr ); // Constructor with parameters
// etc....
};
Date::Date()
{
month = day = year = 1; // Initialize data members
}
Date::Date( int mn, int dy, int yr )
{
setMonth( mn );
setDay( dy );
setYear( yr );
}
void main()
{
Date myDate; // Declare a date without arguments
Date yourDate( 12, 25, 1990 );
myDate.setMonth( 3 ); // Set values for myDate
myDate.setDay( 12 );
myDate.setYear( 1985 );
}
The declaration of myDate doesn't specify any initial values. As a result, the first constructor is used to create myDate and initialize it with the default value “January 1, 1.” The values for myDate are specified later with the set functions. In contrast, the declaration of yourDate specifies three arguments. The second constructor is used to create yourDate, and this constructor calls the member functions to set the data members to the specified values. It is legal for a constructor to call member functions, as long as those functions don't read any uninitialized data members.
The first constructor in the example above is known as a “default constructor,” because it can be called without arguments. If you define a default constructor, the compiler calls it automatically in certain situations; see topic , “Member Objects,” and topic , “Arrays of Class Objects” in Chapter 6.