I am teaching myself C++ and just learning about classes. To practice, I created a Date
class with some methods. I am currently attempting to practice on this problem:
Use the
Date
class to create a method that compares two Date objects and returns the larger of the two.
So I already have some code and methods I made below. Here is where I am confused: When you call a method, its of this form: <object>.<method>
. Say I have two Date objects date1
and date2
. I dont understand how to create a date method that takes two date objects because the method already is acting on one of objects. In other words, I would have expected to have something like this: date1.compareDate(date2)
and this method would have returned the object that has a greater value. Can someone please explain how I do this problem?
I attempted to do this in my method: compareDate(). I made another method convert which creates an integer of the form YYYYMMDD and I can just use simple boolean logic to compare the greater value.
Please note I want to return the larger Date
object and not a bool value.
Thank you in advance.
#include <iostream>
#include <iomanip>
using namespace std;
// Class declaration statement
class Date
{
private:
int month;
int day;
int year;
public:
Date(int = 7, int = 4, int = 2012); // Constructor
void setDate(int, int, int); // Member to copy a date
void showDate(); // Member method to display date
int convert();
bool leapYear();
string dayOfWeek();
void nextDay();
void priorDay();
Date compareDate(Date, Date);
};
// Class Implementation section
Date::Date(int mm, int dd, int yyyy)
{
month = mm;
day = dd;
year = yyyy;
}
void Date::setDate(int mm, int dd, int yyyy)
{
month = mm;
day = dd;
year = yyyy;
}
void Date::showDate()
{
cout << "The date is ";
cout << setfill('0')
<< setw(2) << month << '/'
<< setw(2) << day << '/'
<< setw(2) << year % 100;
cout << endl;
}
int Date::convert()
{
// Convert date to the integer format: YYYYMMDD
return year*10000 + month*100 + day;
}
bool Date::leapYear()
{
if( (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) )
return true;
else
return false;
}
string Date::dayOfWeek()
{
int dayInt;
int mm, yyyy, dd, YYYY;
int century, T, dayOfWeek;
yyyy = year;
mm = month;
dd = day;
if( mm < 3 )
{
mm = mm + 12;
yyyy = yyyy - 1;
}
century = int( yyyy/100 );
YYYY = yyyy%100;
T = dd + int( 26 * (mm + 1)/10) + YYYY + int(YYYY/4) + int( century/4)
-2*century;
dayOfWeek = T % 7;
if( dayOfWeek < 0 )
dayOfWeek += 7;
if( dayOfWeek == 0 )
return "Saturday";
else if( dayOfWeek == 1)
return "Sunday";
else if( dayOfWeek == 2)
return "Monday";
else if( dayOfWeek == 3)
return "Tuesday";
else if( dayOfWeek == 4)
return "Wednesday";
else if( dayOfWeek == 5)
return "Thursday";
else if( dayOfWeek == 6)
return "Friday";
else
{
cout << "dayOfWeek = " << dayOfWeek << endl;
return "Bad dayOfWeek Calc";
}
}
void Date::nextDay()
{
// Increment month and day if at 31 days in month
// Skip December because have to increment year too
if( (month == 1 || month == 3 || month == 5 || month == 7 ||
month == 8 || month == 10) && day == 31 )
{
month++;
day = 1;
}
// Increment month and day if at 30 days in month
else if( (month == 4 || month == 6 || month == 9 || month == 11)
&& day == 30)
{
month++;
day = 1;
}
// New year
else if( month == 12 && day == 31 )
{
month = 1;
day = 1;
year++;
}
// Leap year
else if( leapYear() && month == 2 && day == 29 )
{
month = 3;
day = 1;
}
// Not leap year
else if( !leapYear() && month == 2 && day == 28)
{
month = 3;
day = 1;
}
// Regular day
else
day++;
}
void Date::priorDay()
{
// Increment month and day if at 31 days in month
// Skip December because have to increment year too
if( (month == 5 || month == 7 ||
month == 8 || month == 10 || month == 12) && day == 1 )
{
month--;
day = 30;
}
// Increment month and day if at 30 days in month
else if( (month == 2 || month == 4 || month == 6 || month == 9 || month == 11)
&& day == 1)
{
month--;
day = 31;
}
// beginning year
else if( month == 1 && day == 1 )
{
month = 12;
day = 31;
year--;
}
// Leap year
else if( leapYear() && month == 3 && day == 1 )
{
month--;
day = 29;
}
// Not leap year
else if( !leapYear() && month == 3 && day == 1)
{
month--;
day = 28;
}
// Regular day
else
day--;
}
Date Date::compareDate(Date date1, Date date2)
{
// Return the greater date
if( date1.convert() > date2.convert() )
return date1;
else
return date2;
}
int main()
{
Date c(4,1,2000);
Date d(11, 1, 2013);
b.setDate(12,25,2009);
cout << Date.compareDate(c,d) << endl;
return 0;
}
You can compare your Date objects using operator (which you should write yourself)
friend bool operator> (const Date& D1, const Date& D2)
{
return D1.convert() > D2.convert();
}
This operator is supposed to return true, if and only if D1 > D2. If this operator needs access to private parts of the Date object, then it must be declared as friend inside your Date class.
First of all, make all the functions that don't alter your class const:
int convert() const;
Add the following operator to your class:
bool operator< (const Date &other) const
{
return convert() < other.convert();
}
Alexey's code would work too, but I prefer this one for two reasons: first, one shouldn't introduce friend functions whenever one can add member functions instead, and second, operator< is more important than operator> if you are going to use stl containers or algorithms. stl::set, stl::map, stl::sort all use operator<.
You can create a (freestanding) function that takes two Date
s, as has been stated.
You can also create a Date
method which ignores this
, takes and compares two dates, and returns one of them. This is what you have done. But you still have to call this method through an instance. Also compensating for the lack of a <<
overload:
c.compareDate(c,d).showDate();
works. But of course it would be bad practice because you're asking for an instance ( c.
) where none is required.
What you were trying to do,
Date.compareDate(c,d)
suggests that you were looking for static methods. You need to declare them thus:
class Date {
...
static Date compareDate(Date, Date);
};
and call them like this:
Date::compareDate(c,d).showDate();
(You also could also have a method, Date compareDate(Date)
, that compares this
to the parameter, but that would also be Bad.)
--
You should pick a better name for compareDate
as it isn't currently clear that it's returning a brand new Date
object.
Note that all the previous answers here (as well as the first version of mine) mistakenly thought you wanted to return bool
. That's because that's how comparisons should be done, preferably with an operator<
overload.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.