题解 | #日期累加#
日期累加
https://www.nowcoder.com/practice/eebb2983b7bf40408a1360efb33f9e5d
#include<iostream> #include<assert.h> using namespace std; class date { //友元声明 friend ostream& operator<<(ostream& out, const date& d); public: //初始化列表 date(int y, int m, int d) :_y(y) , _m(m) , _d(d) {} //声明与定义分类 date operator+(int count); //不加coonst的原因: // 代码中,GetMonthDay 函数被声明为 date 类的一个成员函数,但是它没有被声明为 const 成员函数。 // 然而,在 operator+ 函数的实现中,你尝试在一个 const 引用的 date 对象上调用 GetMonthDay,这会导致编译器报错,因为 const 对象不能调用非 const 成员函数 // 总之:当你在一个 const 对象上调用非 const 成员函数时,编译器会报错,因为非 const 成员函数可能会修改对象的状态,这与 const 对象的不变性原则相违背 //类里面默认内联,频繁调用的小函数使用内联更为合适 int GetMonthDay(int y, int m) { assert(m > 0 && m < 13); //因为要频繁调用,所以放到静态区里面比较合适 static int MonthDay_arr[13] = { -1,31,28,31,30,31,30,31,31,30,31,30,31 }; if (m == 2 && (y % 4 == 0 && y % 100 != 0) || y % 400 == 0) { return 29; } return MonthDay_arr[m]; } void Print() const; private: int _y = 0; int _m = 0; int _d = 0; }; //声明与定义分离 date date::operator+(int count) { //operator+ 应该返回一个新创建的 date 对象,而不是修改传入的对象。这是符合算术运算符重载的常规做法,所以使用中间变量tmp date tmp = *this; tmp._d += count; while (tmp._d > GetMonthDay(tmp._y, tmp._m)) { tmp._d -= GetMonthDay(tmp._y, tmp._m); tmp._m++; if (tmp._m == 13) { tmp._m = 1; tmp._y++; } } return tmp; } //由于在date类中this与cout,<<的位置关系不符合我们的表观印象,所以将重载的流>>单独封装,再用友元函数去“借”date类中的私有对象 //ostream& operator<<(ostream& cout, const date& _date) //{ // //... // //其实C语言那套也挺好 //} void date::Print() const { printf("%04d-%02d-%02d\n", _y, _m, _d); } //io流,you also can try it ostream& operator<<(ostream& out, const date& d) { if (d._m < 10 && d._d < 10) out << d._y << "-" << 0 << d._m << "-" << 0 << d._d; else if (d._m >= 10 && d._d < 10) out << d._y << "-" << d._m << "-" << 0 << d._d; else if (d._m < 10 && d._d >= 10) out << d._y << "-" << 0 << d._m << "-" << d._d; else out << d._y << "-" << d._m << "-" << d._d; return out; } int main() { //执行''程序''的次数 int n = 0; int y, m, d; cin >> n; //要加的天数 int count = 0; for (int i = 0; i < n; i++) { cin >> y >> m >> d >> count; //构造 date now_date(y, m, d); date new_date = now_date + count; new_date.Print(); //cout << new_date << endl; } return 0; }