开发者

C++日期类运算符重载方式

目录
  • 构造函数
  • 拷贝构造
  • 赋值运算符重载
  • “+” 日期+天数
  • “-” 日期-天数
  • “+=” 日期+=天数
  • “-=” 日期-=天数
  • 前置"++"
  • 后置"++"
  • 前置"–"
  • 后置"- -"
  • “==”
  • “>”
  • “<”
  • “-” 日期-日期
  • 设置年、月、日
  • 获取年、月、日
  • 判断闰年
  • 获取当前月天数
  • 日期类完整代码
  • 总结

构造函数

定义一个全缺省的构造函数,函数体内判断当前日期是否合法,如果是非法日期,则初始化为2022,1,1

Date(int year=2022, int month=1, int day=1)
  :_year(year)
  , _month(month)
  , _day(day)
 {
  if (year <1 || month < 1 || phpmonth>12 || day<1 || day>GetDayOfMonth(year,month))
  {
   _year = 2022;
   _month = 1;
   _day = 1;
  }
 }

拷贝构造

 Date(const Date& d)
 {
  _year = d._year;
  _month = d._month;
  _day = d._day;
 }

赋值运算符重载

赋值运算符编译器会默认生成,对于日期类可以不用自己定义,自己定义需要注意三点:

  • 参数和返回值都是类类型的引用
  • 判断是否为自己给自己赋值,因为两对象不能直接比较,所以判断时用地址
  • 为了支持连续赋值,必须返回*this
 Date& operator=(const Date& d)
 {
  //不能用对象直接比较,只能比较地址
  //if (d != (*this))
  if(&d!=this)
  {
   _year = d._year;
   _month = d._month;
   _day = d._day;
  }
  return *this;
 }

“+” 日期+天数

"+“与”+=“区分,”+"不改变原变量的值,只是通过返回值返回,所以这里要定义一个临时变量temp,由于temp是保存在栈上的临时变量,所以返回值为Date类型,不能返回引用

先判断正负,如果加的数是负数,则复用"-"的重载

加完后判断_day的合法性,如果_day非法,_day减去当前月份的天数,月份增加,直到日期合法

  //日期+天数
 Date operator+(int day)
 {
  //不能改变原有日期,所以要定义临时变量
  //临时变量不能返回引用
  if (day < 0)
  {
   day = -day;
   return *this - day;
  }
  Date temp=*this;
  temp._day += day;
  while (temp._day > GetDayOfMonth(_year, _month))
  {
   temp._day -= GetDayOfMonth(temp._year,temp._month);
   temp._month++;
   if (temp._month > 12)
   {
    temp._month = 1;
    temp._year++;
   }
  }
  return temp;
 }

“-” 日期-天数

与"+"同原理,如果_day减为0或者负数,先将月份下调一个月,再将日加上上调后月份的天数,如8月0日表示7月31,8月-1日,则表示7月30日。

 //日期-天数
 Date operator-(int day)
 {
  if (day < 0)
  {
   day = -day;
   return *this + day;
  }
  Date temp = *this;
  temp._day -= day;
  while (temp._day <= 0)
  {
   temp._month--;
   if (temp._month < 1)
   {
    temp._year--;
    temp._month = 12;
   }
   temp._day += GetDayOfMonth(temp._year ,temp._month);
  }
  return temp;
 }

“+=” 日期+=天数

"+=“与”+“的区别是,加后要个自己赋值,所以返回类类型对象的引用,可以复用”=“和”+"的重载

 //日期+=天数
 Date& operator+=(int days)
 {
  //复用=和+
  //这里要先将加的和赋值给*this,再返回
  //非常量左值引用只能引用非常量左值
  //如果要直接return(*this + days),返回值类型应为Date&&
  *this = *this + days;
  return * this;
 }

“-=” 日期-=天数

 //日期-=天数
 Date& operator-=(int days)
 {
  *this = *this - days;
  return *this;
 }

前置"++"

前置"++"返回的是加一后的值,可以直接给*this加一后返回

 //前置++
 Date& operator++()
 {
  *this += 1;
  return *this;
 }

后置"++"

C++中,后置"++“参数加一个int,无实际意义,区分前置与后置”++“,由于后置”++"要返回的是自增之前的值,所以要定义一个临时变量,自增后返回该临时变量的值

 //后置++
 //
 Date operator++(int)
 {
  //返回的是自增之前的值
  Date temp = *this;
  *this += 1;
  return temp;
 }

前置"–"

与前置"++"原理相同

 //前置--
 Date& operator--()
 {
  *this -= 1;
  return *this;
 }

后置"- -"

与后置"++"原理相同

 //后置--
 Date operator--(int)
 {
  Date temp = *this;
  *this-= 1;
  return temp;
 }

“==”

判断每变量是否相等

 //==
 bool operator==(Date& d)const
 {
  return d._year == _year &&
   d._month == _month &&
   d._day == _day;
 }

“>”

从年到月日依次判断

 //>
 bool operator>(Date& d)const
 {
  if (_year > d._year)
  {
   return true;
  }
  else if (_year == d._year && _month > d._month)
  {
   return true;
  }
  else if (_year == d._year && _month == d._month && _day > d._day)
  {
   return true;
  }
  else
  {
   return false;
  }
 }

“<”

 //<
 bool operator<(Date& d)const
 {
  if (_year < d._year)
  {
   return true;
  }
  else if (_year == d._year && _month < d._month)
  {
   return true;
  }
  else if (_year == d._year &开发者_开发学习& _month == d._month && _day < d._day)
  {
   return true;
  }
  else
  {
   return false;
  }
 }

“-” 日期-日期

定义一个计数器统计从小的日期到大的日期需要自增多少次

 int operator-(const Date& d)const
 {
  int count = 0;
  Date start(*this);
  Date end(d);
  //保证大的日期减小的日期
  if (start>end)
  {
   Date temp = end;
   end = start;
   start = temp;
  }
  while(end>start)
  {
   start++;
   count++;
  }
  return count;
 }

设置年、月、日

对外部提供修改对象值的接口

 void SetYear(int year)
 {
  _year = year;
 }

 void SetMonth(int month)
 {
  _month = month;
 }

 void SetDay(int day)
 {
  _day = day;
 }

获取年、月、日

向外部提供获取类成员变量值的接口

 int GetYear()const
 {
  return _year;
 }

 int GetMonth()const
 {
  return _month;
 }
 
 int GetDay()const
 {
  return _day;
 }

判断闰年

判断闰年,可以定义为private,不用暴露给外部

 bool IsLeapYear(int year)
 {
  if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
  {
   return true;
  }
  return false;
 }

获取当前月天数

定义一个数组保存每月的天数,根据传进来的年和月返回当前月份的天数

 //获取当前月份的天数
 int GetDayOfMonth(int year, int month)
 {
  int arr[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
  if (IsLeapYear(year))
  {
   arr[2] = 29;
  }
  return arr[month];
 }

日期类完整代码

class Date
{
public:
 //全缺省构造函数
 Date(int year=2022, int month=2, int day=2)
  :_year(year)
  , _month(month)
  , _day(day)
 {
  if (year <1 || month < 1 || month>12 || day<1 || day>GetDayOfMonth(year,month))
  {
   _year = 2022;
   _month = 1;
   _day = 1;
  }
 }
 //拷贝构造
 Date(const Date& d)
 {
  _year = d._year;
  _month = d._month;
  _day = d._day;
 }
 //析构——无实际意义
 ~Date()
 {
  cout << "~Date()" << endl;
 }

 //赋值运算符重载(不写也可以,编译器会默认生成)
 Date& operator=(const Date& d)
 {
  //不能用对象直接比较,只能比较地址
  //if (d != (*this))
  if(&d!=this)
  {
   _year = d._year;
   _month = d._month;
   _day = d._day;
  }
  return *this;
 }

 //日期+天数
 Date operator+(int day)
 {
  //不能改变原有日期,所以要定义临时变量
  //临时变量不能返回引用
  if (day < 0)
  {
   day = -day;
   return *this - day;
  }
  Date temp=*this;
  temp._day += day;
  while (temp._day > GetDayOfMonth(_year, _month))
  {
   temp._day -= GetDayOfMonth(temp._year,temp._month);
   temp._month++;
   if (temp._month > 12)
   {
    temp._month = 1;
    temp._year++;
   }
  }
  return temp;
 }

 //日期-天数
 Date operator-(int day)
 {
  if (day < 0)
  {
   day = -day;
   return *this + day;
  }
  Date temp = *this;
  temp._day -= day;
  while (temp._day <= 0)
  {
   temp._month--;
   if (temp._month < 1)
   {
    temp._year--;
    temp._month = 12;
   }
   temp._day += GetDayOfMonth(temp.编程_year ,temp._month);
  }
  return temp;
 }

 //日期+=天数
 Date& operator+=(int days)
 {
  //复用=和+
  //这里要先将加的和赋值给*this,再返回
  //非常量左值引用只能引用非常量左值
  //如果www.devze.com要直接return(*this + days),返回值类型应为Date&&
  *this = *this + days;
  return * this;
 }

 //日期-=天数
 Date& operator-=(int days)
 {
  *this = *this - days;
  return *this;
 }

 //前置++
 Date& operator++()
 {
  *this += 1;
  return *this;
 }
 //后置++
 //C++语法,后置++参数加一个int,无实际意义,区分前置与后置++
 Date operator++(int)
 {
  //返回的是自增之前的值
  Date temp = *this;
  *this += 1;
  return temp;
 }

 //前置--
 Date& operator--()
 {
  *this -= 1;
  return *this;
 }

 //后置--
 Date operator--(int)
 {
  Date temp = *this;
  *this-= 1;
  return temp;
 }
 //==
 bool operator==(Date& d)const
 {
  return d._year == _year &&
   d._month == _month &&
   d._day == _day;
 }

 //>
 bool operator>(Date& d)const
 {
  if (_year > d._year)
  {
   return true;
  }
  else if (_year == d._year && _month > d._month)
  {
   return true;
  }
  else if (_year == d._year && _month == d._month && _day > d._day)
  {
   return true;
  }
  else
  {
   return false;
  }
 }

 //<
 bool operator<(Date& d)const
 {
  if (_year < d._year)
  {
   return true;
  }
  else if (_year == d._year && _month < d._month)
  {php
   return true;
  }
  else if (_year == d._year && _month == d._month && _day < d._day)
  {
   return true;
  }
  else
  {
   return false;
  }
 }
 //日期-日期 即还有多少天到某一天
 int operator-(const Date& d)const
 {
  int count = 0;
  Date start(*this);
  Date end(d);
  //保证大的日期减小的日期
  if (start>end)
  {
   Date temp = end;
   end = start;
   start = temp;
  }
  while(end>start)
  {
   start++;
   count++;
  }
  return count;
 }

 //设置年、月、日接口
 void SetYear(int year)
 {
  _year = year;
 }

 void SetMonth(int month)
 {
  _month = month;
 }

 void SetDay(int day)
 {
  _day = day;
 }

 //获取年、月、日接口
 int GetYear()const
 {
  return _year;
 }

 int GetMonth()const
 {
  return _month;
 }
 
 int GetDay()const
 {
  return _day;
 }
privat编程e:
 int _year;
 int _month;
 int _day;
 //判断闰年
 bool IsLeapYear(int year)
 {
  if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
  {
   return true;
  }
  return false;
 }

 //获取当前月份的天数
 int GetDayOfMonth(int year, int month)
 {
  int arr[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
  if (IsLeapYear(year))
  {
   arr[2] = 29;
  }
  return arr[month];
 }
};

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新开发

开发排行榜