c++类和对象重要巩固练习-------日期类对象

这是对于类和对象的练习篇,用c++来模拟完成日期计算器。

这其中需要我们完成:

  1. 日期 +- 天数后  得到的新日期 
  2. 日期 - 日期  得到相差的天数
  3. 比较日期的大小
  4. 等 .....
  5. 具体如下头文件类中的成员函数
    #pragma once
    #include<iostream>
    using namespace std;
    #include<assert.h>
    #include<math.h>
    
    
    class Date
    
    {
    	
    public:
    
    	// 获取某年某月的天数
    
    	int GetMonthDay(int year, int month);
    
    	// 全缺省的  构造函数
    
    	Date(int year = 1900, int month = 1, int day = 1)
    	{
    		if (month <= 12 && month > 0 && day <= GetMonthDay(year, month) && day > 0)
    		{
    			_year = year;
    			_month = month;
    			_day = day;
    		}
    		else
    		{
    			cout << "非法日期" << endl;
    			assert(0);
    		}
    	}
    	// 拷贝构造函数
    
      // d2(d1)
    
    	Date(const Date& d)
    	{
    		_year = d._year;
    		_month = d._month;
    		_day = d._day;
    	}
    	
    	void Print()const
    	{
    		cout << _year << ' ' << _month << ' ' << _day << endl;
    	}
    
    	// 赋值运算符重载
    
      // d2 = d3 -> d2.operator=(&d2, d3)
    
    	Date& operator=(const Date& d)
    	{
    		if (this != &d)//比较地址(比较地址比较简单),减少 d1=d1 这种赋值情况
    		{
    			_year = d._year;
    			_month = d._month;
    			_day = d._day;
    		}
    
    		return *this;
    	}
    
    
    	// 析构函数
    
    	// 日期+=天数
    
    	Date& operator+=(int day);
    
    	// 日期+天数
    
    	Date operator+(int day)const;
    
    	// 日期-天数
    
    	Date operator-(int day)const;
    
    	// 日期-=天数
    
    	Date& operator-=(int day);
    
    	// 前置++
    
    	Date& operator++();
    
    	// 后置++
    
    	Date operator++(int);
    
    	// 后置--
    
    	Date operator--(int);
    
    
    	// 前置--
    
    	Date& operator--();
    
    
    	// >运算符重载
    
    	bool operator>(const Date& d)const;
    
    	// ==运算符重载
    
    	bool operator==(const Date& d)const;
    
    
    
    	// >=运算符重载
    
    	bool operator >= (const Date& d)const;
    
    
    
    	// <运算符重载
    
    	bool operator < (const Date& d)const;
    
    
    
    	// <=运算符重载
    
    	bool operator <= (const Date& d)const;
    
    
    
    	// !=运算符重载
    
    	bool operator != (const Date& d)const;
    
    
    
    	// 日期-日期 返回天数
    
    	int operator-(const Date& d)const;
    
    private:
    
    	int _year;
    
    	int _month;
    
    	int _day;
    
    };
    

实现过程  (一些实现的细节已经注释):

  1.  日期类的 += 日期  
    int Date::GetMonthDay(int year, int month)
    {
    
    	static int arr[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };//因为该数组会被经常的调用所以可以直接放到静态区
    	if (month == 2 && year % 4 == 0 && year % 100 != 0 || year % 400 == 0)//对2月闰年单独讨论
    	{
    		return 29;
    	}
    	else
    	{
    		return arr[month];
    	}
    }
    
    
    //返回 引用可以减少拷贝的损耗
    //其中返回 Date 类型还能帮助我们实现连续操作
    Date& Date::operator+=(int day)
    {
    	if (day < 0)//为了当传进来是-的天数也能使用
    	{
    		*this -= (-day);//-= 在后面实现
    		return *this;
    	}
    	_day += day;//用进位的方法来算,先加上天数
    	while(_day > GetMonthDay(_year,_month))//如果天数大于该月的月数就进位
    	{
    		_day -= GetMonthDay(_year, _month);//在进位后就需要把上月的天数剪掉
    
    		//注意这些应该写在后面
    		_month++;
    		if (_month > 12)//当月到了12时也要进位
    		{
    			_month = 1;
    			_year++;
    		}
    	}
    	return *this;
    }
  2. 日期类的 + 日期
    Date Date::operator+(int day)const
    {
    	//我们在使用 + 时有时是不需要去改变值的 如  a + 2 ; a 并没有改变
    	Date tmp(*this);//创建一个临时变量
    	//if (day < 0)
    	//{
    	//	tmp -= abs(day);
    	//	return tmp;
    	//}
    	tmp += day;//对临时变量 += 
    	return tmp;//返回临时变量即可
    
    	//下面其实是一些重复的动作我们可以通过再次调用+=
    	 
    	//tmp._day += day;
    	//while (tmp._day > GetMonthDay(_year, _month))
    	//{
    	//	tmp._day -= GetMonthDay(_year, _month);
    
    	//	//注意这些应该写在后面
    	//	tmp._month++;
    	//	if (tmp._month > 12)
    	//	{
    	//		tmp._month = 1;
    	//		tmp._year++;
    	//	}
    	//}
    	//return tmp;
    }
  3. 日期类的 -= 日期

    Date& Date::operator-=(int day)
    {
    	if (day < 0)//同理当day < 0 时就相当于 += 
    	{
    		*this += (-day);
    		return *this;
    	}
    	_day -= day;//先减去一定的天数
    	while (_day <= 0)//不断的借位,只到借到正常的天数
    	{
    		_month--;
    		if (_month < 1)
    		{
    			_month = 12;
    			_year--;
    		}
    		//注意此时day += 应该写在后面 因为是要向前借位
    		_day += GetMonthDay(_year, _month);//加上前一个月的月份,接一位
    	}
    	return *this;
    }
  4. 日期类的-天数

    Date Date::operator-(int day)const//和 + 一样直接通过临时变量的传递即可
    {
    
    	Date tmp(*this);
    	tmp -= day;
    	return tmp;
    
    }
    
  5. 日期类的 ++

    1. 注意此时是要分 前置 和 后置

    2. 对于前置来说 我们就正常的写 运算符重载函数即可

    3. 而 对于 后置来说 写运算符重载函数时 需要一个参数来占位(与前置形成重载函数)

    4. 具体源码如下 

      Date& Date::operator++()//前置 ++ 
      {
      	*this += 1;//直接++即可
      	return *this;
      }
      
      
      Date Date::operator++(int) // 后置 ++ 通过一个参数来占位 构成函数重载来区分
      {
      	Date tmp(*this);// 因为是后置 ++ 所以用临时变量传回去之前前的值
      	*this += 1;//实则已经改变了
      	return tmp;
      }
  6. 日期类的 --

    1. 同样分前置和后置

    2. 就不过多赘述了,和++一样

    3. 具体如下:

      Date& Date::operator--()//前置
      {
      	*this -= 1;
      	return *this;
      }
      
      Date Date::operator--(int)//后置
      {
      	Date tmp(*this);
      	*this -= 1;
      	return tmp;
      }
  7. 日期类的比较 >   >=  ==   !=     <    < =  (总体来说较为简单

    1. 对于这类比较性的我们其实可以先写出 < 、==  /  >、==   其余的复用即可

    2. 具体如下

      bool Date::operator>(const Date& d)const
      {
      	if (_year < d._year)//先判断是否小于,若否则是  等于(继续判断)或 大于(直接结束)
      	{
      		return false;
      	}
      	else if (_year == d._year && _month < d._month)//同理
      	{
      		return false;
      	}
      	else if (_year == d._year && _month == d._month && _day < d._day)
      	{
      		return false;
      	}
      	else
      	{
      		return true;
      	}
      }
      
      bool Date::operator==(const Date& d)const//简单的判断
      {
      	return (_year == d._year && _month == d._month && _day == d._day);
      }
      
      bool Date::operator>=(const Date& d)const
      {
      	return *this > d || *this == d;
      
      }
      
      bool Date::operator <= (const Date& d)const
      {
      	return !(*this > d);
      }
      
      bool Date::operator < (const Date& d)const
      {
      	return !(*this >= d);
      }
      
      bool Date::operator != (const Date& d)const
      {
      	return !(*this == d);
      }
  8. 日期 - 日期

    1. 对于日期 - 日期 我们用遍历法来实现

    2. 具体如下

      int Date::operator-(const Date& d)const
      {
      	int tag = 1;
      	Date Max(*this);//先确立大的为*this
      	Date Min(d);//把 d 看成小的
      	if (Max < Min)//如果 Max < Min 就交换
      	{
      		Min = *this;
      		Max = d;
      		tag = -1;// 交换后表示前面的值要小于后面的值 , 所以把 tag 置为负的
      	}
      	int count = 0;
      	while (Min < Max)//看看相差多少 ,逐一相加
      	{
      		count++;
      		++Min;
      	}
      	return count * tag;
      }
      

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

溟洵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值