默认成员函数的应用场景:
Date date1; //当我们实例化一个对象date1时,就会调用 构造函数,所以我们可以使用构造函数对对象进行初始化。
Date date2 = date1; //当我们实例化对象date2的同时将一个已存在的对象的内容拷贝过来,就会调用拷贝构造函数。
Date date3; date3 = date1; //一个对象往往是一个复杂的结构体(C语言叫法),我们希望可以将一个对象(结构体)当做一个普通变量来操作,甚至希望其操作方式可以被我们所规定,此时就要用到“操作符重载函数”,这里只是给出了 = 的重载函数。
析构函数:我们在实例化一个对象后,其在内存中就被分配了空间。我们程序结束后(或者当该对象的生命周期结束时),我们需要释放这一部分空间,这就会调用析构函数。 对象析构的顺序严格按照实例化的顺序进行析构。
Date::Date(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
Date::Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
Date& Date::operator=(const Date& d)
{
if (this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
Date::~Date()
{
_year = 1900;
_month = 1;
_day = 1;
}
思路:这个比较简单,只需要判断二个对象的私有成员对象值是否相等即可。
bool Date::operator==(const Date& d)
{
if (this->_year == d._year && this->_month == d._month && this->_day == d._day)
{
return true;
}
else
{
return false;
}
}
思路:日期类的前置++,我们认为是将天数++,再返回。
这里需要注意的是:
(1)天数++后,需要对日期进行更新,防止出现32号这种尴尬的情况。
(2)这里返回*this,相比较在这里构造一个临时变量再返回临时变量,可以减少一次拷贝重构的次数,提高程序的运行效率。
Date& Date::operator++() //前置++
{
this->_day++;
DateDayUP();
return *this;
}
//日期更新函数
void Date::DateDayUP() //日期改变后的更新,只适用于日期++ --
{
if (this->_day == GetMonthDay(this->_year, this->_month) + 1)
{
this->_month++;
this->DateUp();
this->_day = 1; //下一月的1号
}
if (this->_day == 0)
{
this->_month--;
this->DateUp();
this->_day = GetMonthDay(this->_year, this->_month);
}
}
思路:后置++是先使用对象的值,再让原对象++。 所以我们先创建一个临时对象,承接原对象,再让原对象++,最后返回临时变量的内容。
在重载++运算符时,operator++(int)表示后置++,operator++()表示前置++,这是规定,不可混淆。
Date Date::operator++(int) //后置++
{
Date Dates = *this;
this->operator++();
return Dates;
}
思路:--运算符的重载和++运算符的重载类似。
Date& Date::operator--() //前置--
{
this->_day--;
DateDayUP();
return *this;
}
Date Date::operator--(int) //后置--
{
Date Dates = *this;
this->operator--();
return Dates;
}
思路:一个日期类对象>另一个日期类对象。我们需要从year开始比较,再比较month,最后比较day。
bool Date::operator>(const Date& d)
{
if (this->_year > d._year)
{
return true;
}
else if (this->_year == d._year)
{
if (this->_month > d._month)
{
return true;
}
else if (this->_month == d._month)
{
if (this->_day > d._day)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
}
bool Date::operator < (const Date& d)
{
if (this->_year < d._year)
{
return true;
}
else if (this->_year == d._year)
{
if (this->_month < d._month)
{
return true;
}
else if (this->_month == d._month)
{
if (this->_day < d._day)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
}
bool Date::operator != (const Date& d)
{
if (this->_year != d._year || this->_month != d._month || this->_day != d._day)
{
return true;
}
else
{
return false;
}
}
注意:我们写>=运算符重载时,使用的是内联函数,内联函数必须与定义语句在一个文件夹中。
inline bool Date::operator >= (const Date& d)
{
if (this->operator==(d) == true || this->operator>(d) == true)
{
return true;
}
else
{
return false;
}
}
bool Date::operator <= (const Date& d)
{
if (this->operator==(d) == true || this->operator<(d) == true)
{
return true;
}
else
{
return false;
}
}
思路:一个日期类对象+一个自定义天数,返回更新后的日期。
//获取月天数 函数
int Date::GetMonthDay(int year, int month)
{
if (month == 0 || month == 13)
{
return 31;
}
if (month == -1)
{
return 30;
}
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)
{
return 31;
}
else if (month == 4 || month == 6 || month == 9 || month == 11)
{
return 30;
}
else
{
if (DateLeapYear(year))
{
return 29;
}
else
{
return 28;
}
}
}
//判断闰年的函数
int Date::DateLeapYear(int year) //判断是否为闰年
{
if (year % 4 == 0)
{
if (year % 100 == 0)
{
if (year % 400 == 0)
{
return 1;
}
}
else
{
return 1;
}
}
return 0;
}
//+= 运算符重载函数
Date& Date::operator+=(int day)
{
DateDayUP();
while (day > 365 + DateLeapYear(this->_year)) //加的天数超过一年的全部天数
{
day -= 365 + DateLeapYear(this->_year);
this->_year++;
}
this->_day += day;
while (this->_day > GetMonthDay(this->_year, this->_month)) //加的超过一月的最大天数
{
this->_day -= GetMonthDay(this->_year, this->_month);
this->_month++;
this->DateUp(); //更新日期,防止月份超过12
}
//月份加完很有可能超过12个月(但不会超过24个月,也就是year最多+1),此时需要再做出判断
return *this;
}
需要注意的是:我们必须创建临时对象,否则将会改变原对象的值,这是错误的。
Date Date::operator+(int day)
{
//return Date(this->operator+=(day)); //错误, + 不应该改变原本的值
Date Dates = *this;
Dates.operator+=(day);
return Dates;
}
Date& Date::operator-=(int day)
{
while (day - 365 + DateLeapYear(this->_year - 1) > 0)
{
day -= 365 + DateLeapYear(this->_year - 1);
this->_year--;
}
this->_day -= day;
this->DateUp(); //更新日期
while (this->_day + GetMonthDay(this->_year, this->_month - 1) < 0)
{
this->_day += GetMonthDay(this->_year, this->_month - 1);
this->_month--;
this->DateUp(); //更新日期,防止月份低于0
}
this->_month--;
this->DateUp(); //更新日期,防止月份低于0
this->_day += GetMonthDay(this->_year, this->_month);
this->DateUp(); //更新日期
return *this;
}
Date Date::operator-(int day)
{
Date Dates = *this;
return Dates.operator-=(day);
}
int Date::operator-(const Date& d)
{
int DayNum = 0;
Date MaxDate;
Date MinDate;
if (this->operator == (d))
{
return 0;
}
else if (this->operator>(d))
{
MaxDate = *this;
MinDate = d;
}
else
{
MaxDate = d;
MinDate = *this;
}
while (MaxDate._year - MinDate._year > 1)
{
DayNum += 365 + DateLeapYear(MaxDate._year - 1);
MaxDate._year--;
}
if (MaxDate._year != MinDate._year)
{
MaxDate._month += 12 * (MaxDate._year - MinDate._year); //理论上 该值为12*1
}
while (MaxDate._month > MinDate._month)
{
int mon = 0;
if (MaxDate._month > 12)
{
mon = MaxDate._month % 12;
}
else if(MaxDate._month == 12)
{
mon = MaxDate._month;
MaxDate._year--;
}
else
{
mon = MaxDate._month;
}
DayNum += GetMonthDay(MaxDate._year, mon - 1);
MaxDate._month--;
}
DayNum += MaxDate._day - MinDate._day;
return DayNum;
}