Data类
声明和定义分离的一些问题
声明里面我们不带缺省参数,定义我们给缺省参数,如下面两段代码:
Data.h#pragma once
#include<iostream>
using namespace std;
class Data
{
public:Data(int year,int month,int day);private:int _year;int _month;int _day;};
Data.cpp#include"Data.h"Data::Data(int year=1 , int month=1 , int day=1 ){_year = year;_month = month;_day = day;}
现在我们在main函数调用:
d1没报错,d2报错了:
这是因为我们main函数那个文件包的是.h文件,声明我们没有给缺省参数,声明就好比一种承诺,
没给参数,我们d2没有默认参数就过不了。
我们给个默认参数看看:
#pragma once
#include<iostream>
using namespace std;
class Data
{
public:Data(int year = 1, int month = 1, int day = 1);
private:int _year;int _month;int _day;};
声明和定义不能同时给默认参数,我们把定义的默认参数去了就可以了。
OK,我们写个print函数就可以把日期打印出来看看了:
Data.cppvoid Data:: print(){cout << _year << "年" << _month << "月" << _day << "日" << endl;}
我们发现上面这段日期是有问题的,有点的是闰年,有的是13月,是一些不合法日期,所以我们要加日期有效判断。
日期判断
引用上一篇文章写的:
int Getmonth(int year,int month){int GetArry[13] = {0, 31,28,30,31,30,31,30,31,30,31,30,31 };if (month==2&&(month % 4 == 0 && month % 10 == 0 || month % 400 != 0)){return 29;}return GetArry[month];}
可以在Getmonth函数前面加一个static,因为Getmonth肯定会被频繁调用,每一次都进来会造成消耗,所以用static让它具有全局属性。
然后我们给输入的日期加判断:
拷贝构造
日期类需不需要我们自己写拷贝构造,不需要,因为日期类就三个成员变量:int _year ,int _month,int _day,全是内置类型,编译器会自动生成拷贝构造:
Data d1(2003,11,33);d1.print();Data d2(d1);d2.print();
运算符重载
bool Data::operator<=(Data d2)
{if (_year <= d2._year){return true;}if (_year <= d2._year && _month <= d2._month){return true;}if (_year <= d2._year && _month <= d2._month && _day <= d2._day){return true;}else{return false;}
}bool Data::operator==(Data d2)
{return _year == d2._year&& _month == d2._month&& _day == d2._day;
}bool Data::operator>=(Data d2)
{return !(*this <= d2) || *this == d2;
}bool Data::operator<(Data d2)
{return !(*this <= d2);
}bool Data:: operator!=(Data d2)
{return !(*this == d2);
}
赋值运算符重载
Data& Data::operator=(const Data& d3)
{this->_year = d3._year;this->_month = d3._month;this->_day = d3._day;return *this;
}
Data d1(2003, 11, 33);Data d3(2003, 11, 22);Data d4(2000, 12, 3);d1 = d3 = d4;d1.print();d3.print();d4.print();
用operator+ 实现两个日期类相加
用+运算符重载实现两个日期类相加。
直接用上篇文章的内容,如下代码实现两个日期类相加:
Data& Data:: operator+(int day)
{Data temp(*this);//天数相加temp._day += day;//如果月满了while (temp._day > Getmonth(_year, _month)){//天数减去满月的天数temp._day -= Getmonth(_year, _month);//从当前月进入下一个月++temp._month;}//如果12个月都满了if (temp._month == 13){//当前年进入下一年++temp._year;//把月置为下一年的一月temp._month = 1;}return temp;
}
mainData d1(2003, 11, 29);Data d2 = d1 + 200;d1.print();d2.print();
原因:
通过调试发现,都已经超过12月了,还没有进入month==13的判断里面,这是因为whil循环没结束,要么改while循环条件,要么把month==13的if判断放到while里面修改后的代码:
static int Getmonth(int year, int month)
{int GetArry[13] = { 0, 31,28,30,31,30,31,30,31,30,31,30,31 };if (month == 2 && (year% 4 == 0 && year % 100 == 0 || year % 400 != 0)){return 29;}return GetArry[month];
}Data& Data::operator+=(int day)
{*this += day;return *this;
}Data& Data:: operator+(int day)
{Data temp(*this);//天数相加temp._day += day;//如果月满了while (temp._day > Getmonth(_year, _month)){//天数减去满月的天数temp._day -= Getmonth(_year, _month);//从当前月进入下一个月++temp._month;//如果12个月都满了if (temp._month == 13){//当前年进入下一年++temp._year;//把月置为下一年的一月temp._month = 1;}}return temp;
}
mainData d1(2003, 11, 29);d1 += 200;d1.print();
复用 ”+"实现 “+=”
注意不能这样写:
因为我们要服用 "operator+"实现"+=”功能,所以不能使用 “+=",因为"+="功能还没实现。
运行:
Data d1(2003, 11, 29);d1 += 200;d1.print();
operator-=
Date& Date:: operator-=(int day)
{_day -= day;while (_day <=0){--_month;if (_month == 0){_year;_month = 12;}_day += Getmonth(_year, _month);}return *this;
}
如果我们这样写呢?
Date d1(2003, 11, 29);d1 -= -2000;d1.print();
会偏移预期效果:
因为我们没有考虑day为负数的情况。
d1-=2000 ==> d1=d1=-(-2000) ==>d1=d1+2000 ==>d1+=2000;
我们复用一下operator+=就可以了。
Date& Date:: operator-=(int day)
{if (day < 0){return *this += (-day);}
同样的
Date d1(2003, 11, 29);d1 += -2000;d1.print();
也可以复用operator-=
没改之前:
改了之后:
Date& Date::operator+=(int day)
{if (day < 0){return *this -= day;}*this =*this+day;return *this;
}