#include<iostream> using namespace std; class Date { public: //获取一个月中的天数 int GetMonthDay(int year,int month); //构造函数,不要在你的声明和定义中同时写入缺省值 Date(int year, int month, int day); //拷贝构造函数 Date(const Date& d); //== bool operator==(const Date& d); //这里的bool值代表的返回的是真假的情况 //> bool operator>(const Date& d); //>= bool operator>=(const Date& d); //< bool operator<(const Date& d); //<= bool operator<=(const Date& d); //!= bool operator!=(const Date& d); //= Date& Date::operator=(const Date& d); //+= 日期加日期是没有意义的,但是日期加天数就是有意义的 Date& operator+=(int day); //+ Date operator+(int day); //-= Date& Date::operator-=(int day); //- Date Date::operator-(int day); //++(前置) Date& Date::operator++(); //++(后置) Date Date::operator++(int); //--(前置) Date& Date::operator--(); //--(后置) Date Date::operator--(int); //日期-日期也是有意义的 int operator-(const Date& d); void Print(); private: int _year; int _month; int _day; };
#include"Date.h" int Date::GetMonthDay(int year, int month) { //除了2月(和是否是闰年有关),其他的月份的基本天数是不会发生改变的 static int daysArr[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; //因为这个函数会被频繁的调用,如果每次调用都重新开空间写入太过麻烦,所以直接把它扔到静态区 int days = daysArr[month]; //所以这里只剩下2月需要判别 if (month = 2 && (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))//闰年 { days = 29; } return days; } Date::Date(int year, int month, int day) { _year = year; _month = month; _day = day; if (!(year >= 0 && month > 0 && month < 13 && day > 0 && day <= GetMonthDay(year, month))) { cout << "日期非法" << endl; } } void Date::Print() { cout << _year << "-" << _month << "-" << _day << endl; } // = 既然这里是赋值运算符,那么应该有返回值,返回值应该是d2,因为this是d2地址的指针,即使出了作用域,d2依旧存在,所以可以使用引用传参,可以减少两次拷贝 Date& Date::operator=(const Date& d) { //就是要把d3的值给d2 ,这个判断就是避免自己给自己赋值,这个是没有任何意义的 if (this != &d) { _year = d._year; _month = d._month; _day = d._day; } return *this; //虽然这个this不常加,但是这里是需要使用到的 } //d1 + =100,返回值:d1 //先把天加到日期天上。如果日期不合法,就剪掉当月的天数,然后进一个月。再继续看不合法,在继续减掉当月的天数再进月,如果月满,往年进位 Date& Date::operator += (int day) { if (day < 0) { return *this -= -day;//你这个day本身就是-的,所以一个负负就得正了 } _day += day; // 日期是否合法 while (_day > GetMonthDay(_year, _month)) { _day -= GetMonthDay(_year, _month); _month++; if (_month == 13) { _year++; _month = 1; } } return *this;//最后返回的应该是一个日期 } //- 这里和上面一样不能够修改本来的d1值,所以需要拷贝构造函数 Date Date::operator-(int day) { Date ret(*this); ret._day -= day; while (ret._day < 0) { ret._month--; if (ret._month == 0) { ret._year--; ret._month = 12; } ret._day += GetMonthDay(ret._year, ret._month); } return ret; } //- 的简化版: Date Date::operator-(int day) { Date ret(*this); ret -= day; return ret; } // + Date Date::operator+(int day)//第一个Date是返回值,第一个Date是指类;出了作用域ret不存在,所以使用传值Date返回,不使用引用 { // 方法1:跟+=实现,逻辑类似冗余 /*Date ret(*this); ret._day += day; while (ret._day > GetMonthDay(ret._year, ret._month)) { ret._day -= GetMonthDay(ret._year, ret._month); ret._month++; if (ret._month == 13) { ret._year++; ret._month = 1; } } return ret;*/ //方法2: Date ret(*this); ret += day; // 相当于ret.operator+=(day); return ret; } //-= Date& Date::operator-=(int day) { _day -= day; while (_day < 0) { _month--; if (_month == 0) { _year--; _month = 12; } _day += GetMonthDay(_year, _month); } return *this; } // ++d1 等价于 d1 += 1 // 转换为d1.operator++(&d1); // 返回++之后的值 Date& Date::operator++() { *this += 1; return *this; } // d1++ // 转化为:d1.operator++(&d1, 0); // 返回++之前的值 Date Date::operator++(int) { Date ret(*this); *this += 1; return ret; } //传引用的时候,尽量加const ,因为你并不希望修改d1里面本来的值,你只是希望d2和d1相同 // d1 == d2 bool Date::operator==(const Date& d) { return _year == d._year && _month == d._month && _day == d._day; } //年大就是大,年一样的时候,月大就是大,月相同的时候,天大就是大,所有满足的情况考虑足,那么剩下的就只是不满足的了 bool Date::operator>(const Date& d) { if (_year > d._year) { return true; } else if (_year == d._year) { if (_month > d._month) { return true; } else if (_month == d._month) { if (_day > d._day) { return true; } } } return false; } // d1 != d2 bool Date::operator!=(const Date& d) { return !(*this == d);//代码复用bool Date::operator==(const Date& d) } // d1 >= d2 bool Date::operator>=(const Date& d) { return *this > d || *this == d; } // d1 < d2 bool Date::operator<(const Date& d) { return !(*this >= d); } // d1 <= d2 bool Date::operator<=(const Date& d) { return !(*this > d);//代码复用bool Date::operator>(const Date& d) } // d1(即this) - d2(即d) int Date::operator-(const Date& d) { // 直接进行日期之间相减,不好操作 Date max = *this, min = d; int flag = 1; if (*this < d) { max = d; min = *this; flag = -1; } int n = 0; while (min != max) { ++n; ++min;//自定义类型min重载之后,用起来和内置类型感觉一样 }//小的往大的那个方向+,+满之后会自动往月、年上进位,+了多少次=相差多少天 return n*flag; } //构造函数 Date::Date(int year = 1900, int month= 1, int day=1) { if (year>0 && month>0 && month<13 && day>0 && day<GetMonthDay(year,month)) { _year = year; _month = month; _day = day; } else { cout << "日期非法" << endl; } }
#pragma once #include <iostream> using namespace std; class Date { public: int GetMonthDay(int year, int month); void Print(); Date(int year = 1900, int month = 1, int day = 1); // d1 += 10 Date& operator+=(int day); // d1 + 10 Date operator+(int day); // d1 -= 10 Date& operator-=(int day); // d1 - 10 Date operator-(int day); // ++d1 // d1.operator++(&d1); Date& operator++(); // 加了一个用以区别的形参int,这个参数不使用,仅仅是为了跟前置++构成函数重载区分开来 // d1++ // d1.operator++(&d1, 0); Date operator++(int); Date& operator--(); Date operator--(int); // ==运算符重载 bool operator==(const Date& d); // !=运算符重载 bool operator != (const Date& d); // >运算符重载 bool operator>(const Date& d); // <运算符重载 bool operator < (const Date& d); // >=运算符重载 bool operator >= (const Date& d); // <=运算符重载 bool operator <= (const Date& d); // d1 - d2 int operator-(const Date& d); private: int _year; int _month; int _day; };
#include<iostream> using namespace std; #include "Date.h" int main() { Date d1(2021, 2, 3); d1.Print(); Date ret = d1 + 100;//d1没被 改变 ret.Print(); d1 += 100;//d1被 改变 d1.Print(); ret = d1 + -100; ret.Print(); d1++; ++d1; //Date d2(2020, 2, 29); //d2.Print(); //Date d3(2021, 13, 0); //d3.Print(); Date d3(2021, 2, 3); Date d4(2021, 8, 1); cout << d3 - d4 << endl; cout << d4 - d3 << endl; return 0;}
d1 += 100;的计算过程: