Operator overload "-"

I am currently writing a program in which there is a section to determine the difference in days between two dates, but overloading the minus operator.

I am currently looking at my screen, drawing a complete space. I have some fleeting thoughts in my head, but they are just so fleeting.

What happens in main.cpp is that there will be two variables, for example beethovenDeathDate and beethovenBirthDate , which will be subtracted to determine how long it lived. Something about 22,000 days, if I remember correctly.

So, without much ado, here is my code:

Date.cpp

 const std::string Date::MONTH_STRINGS[] = { "", //one based indexing "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; const int Date::DAYS_PER_MONTH[] = { 0, //one based indexing 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; Date::Date(int day, int month, int year) : _year(year), _month(month), _day(day) { isValid(); } Date::Date() { time_t t = time(0); // get time now struct tm * now = localtime( & t ); _year = now -> tm_year + 1900; _month = now -> tm_mon + 1; _day = now -> tm_mday; } int Date::maxDay(int month, int year) { int ret = DAYS_PER_MONTH[month]; if(isLeapYear(year) == true && month == 2) { ++ret; } return ret; } void Date::addDay(bool forward) { if(forward) { if(_day < maxDay(_month, _year)) { ++_day; } else { _day = MIN_DAY; ++_month; if(_month > MAX_MONTH) { _month = MIN_MONTH; ++_year; } } } else { if(_day <= MIN_DAY) { --_month; if(_month < MIN_MONTH) { _month = MAX_MONTH; --_year; } _day = maxDay(_month, _year); } else { --_day; } } } std::string Date::toString() const { if(isValid() == false) { return std::string(); } std::stringstream ss; ss << MONTH_STRINGS[_month] << " " << _day << ", " << _year; return ss.str(); } bool Date::isValid() const { if(_month < MIN_MONTH || _month > MAX_MONTH) { std::cerr << "Invalid date " << std::endl; return false; } int daysThisMonth = maxDay(_month, _year); if(_day < MIN_DAY || _day > daysThisMonth) { std::cerr << "Invalid date " << std::endl; return false; } return true; } bool Date::isLeapYear(int year) { if(!(year % 4)) { if(!(year % 100)) { if(!(year % 400)) { return true; } else { return false; } } else { return true; } } else { return false; } } bool Date::isLeapYear() const { return isLeapYear(_year); } bool Date::isLeapDay() const { return isLeapDay(_day, _month, _year); } bool Date::isLeapDay(int day, int month, int year) { if(day == 29 && month == 2 && isLeapYear(year) == true) { return true; } else { return false; } } void Date::addYears(int years) { if(years == 0) { return; } if(isLeapDay() && !isLeapDay(_day, _month, _year + years)) { _day = Date::DAYS_PER_MONTH[_month]; } _year += years; } void Date::addMonths(int months) { if(months == 0) { return; } int deltayears = months / MAX_MONTH; int deltamonths = months % MAX_MONTH; int newMonth = 0; if(months > 0) { newMonth = (_month + deltamonths) % MAX_MONTH; if((_month + deltamonths) > MAX_MONTH) { ++deltayears; } } else { if((_month + deltamonths) < MIN_MONTH) { --deltayears; newMonth = _month + deltamonths + MAX_MONTH; } else { newMonth = _month + deltamonths; } } if(_day > maxDay(newMonth, _year + deltayears)) { _day = maxDay(newMonth, _year + deltayears); } _year += deltayears; _month = newMonth; } void Date::addDays(int days) { if(days == 0) { return; } if(days < 0) { for(int i = 0; i > days; --i) { addDay(false); } return; } for(int i = 0; i < days; ++i) { addDay(true); } } std::ostream& operator<<(std::ostream& os, const Date& date) { os << date.toString(); return os; } Date Date::operator+(int days) const { Date ret = *this; ret.addDays(days); return ret; } Date& Date::operator+=(int days) { addDays(days); return *this; } //This is where I get stumped (the parameters was just one of my failed experiments Date& Date::operator-(int day, int month, int year) { } 
+4
source share
2 answers

A function can be written either as a member or as a free function. The signature of the member function will look like this:

 TimeDuration Date::operator-(Date const & rhs) const 

A free function would look like this:

 TimeDuration operator-(Date const & lhs, Date const & rhs) 

TimeDuration here is a completely separate type, representing a length of time. If you want, you can just do this int , indicating the number of days, but it would be better, in my opinion, to have a more expressive type for this purpose. No matter what you decide on the return type, Date does not matter for the type (and certainly not Date& ).

A possible (though not incredibly effective) implementation, given that you have already created a function to add a day to a date, will look something like this:

 if lhs_date comes before rhs_date add days to (a copy of) lhs_date until lhs_date == rhs_date return the negative of number of days added if rhs_date comes before lhs_date add days to (a copy of) rhs_date until rhs_date == lhs_date return the number of days added else return 0 

Another function that you may want (or perhaps this is what you actually wanted initially, but your wording does not indicate it) is a function that can subtract the duration from Date . In this case, the return value will be another Date object (but not Date& ), and the possible signatures will look something like this:

 Date Date::operator-(TimeDuration rhs) const // member version Date operator-(Date const & lhs, TimeDuration const & rhs) // non-member version 
+2
source

You must do this:

 //This is where I get stumped (the parameters was just one of my failed experiments TimeDuration& Date::operator-(Date const & d1) { // ... processing ... // this - d1; } 

and name it like:

 Date d1 = new Date(20, 01, 2013); TimeDuration duration = d1 - (new const Date(20, 01, 1922)); // Calculate no. of days or years using duration 

The logic is as follows:

  • Pass two Date objects (the first may be implicit) to the overload function and return TimeDuration

  • To call this statement, you can create a Date object with the data you have, instead of passing each value separately.

Check the exact syntax.

0
source

Source: https://habr.com/ru/post/1501392/


All Articles