经典面试题-(日期类的实现)

【摘要】过去我们因为接触的数据类型比较少,因此不需要对运算符有太多的要求,但是自从我们开始学习C++之后,有了类的概念,如果我们仍想要对类中的对象进行一些操作,那就必须得实现操作符的重载了。


       如果我们想要完成关于日期的一些操作,就像简单的加减,日期里面乘除没有意义。还有比如说算两个日期差的天数,用普通的操作符是很难实现的,因此,我们需要重载运算符,使它可以完成日期类的操作。

首先,我们需要分析出一个日期类要完成那些操作?
1.最起码的加减天数然后得到若干天之后或者之前的日期

2.两个日期相减,算出中间差的天数
3.日期的自增和自减

4.比较日期的大小
有了这些基本的需求,我们就可以按步骤取实现我们的日期类了

1.日期类中必须有 年,月,日 三个私有数据,我们可以在类中写出一个构造函数对数据进行显式地初始化。
2.定义需要的成员函数,基本上囊括上述的几种功能。
3.把类中的成员函数声明之后,在类外进行定义。(记得一定要在函数名前面加上类名,我定义的类叫Date,不然函数就没办法调用类中的参数)

4.测试用例,把所有可能出现的情况都进行测试,保证程序可以全部顺利通过。
一点小建议:

    因为日期类的实现代码量还是很大的,如果全部写好之后再进行调试有可能会遇到大量的错误,这时候调试起来是相当麻烦,所以读者可以每实现一个函数就进行一次调试,这样可以保证整个工程写完之后没有很多的错误。
下面是实现代码以及测试用例的结果
#include<iostream>
#include<stdlib.h>
#include<assert.h>

using namespace std;

class Date 
{ 
public: 
       Date(int year = 1900, int month = 1, int day = 1) 
		   :_year(year) 
	     ,_month(month) 
         ,_day(day) 
	   {
          if(month<1  || month>12 || day<0 || day>GetMonthDay(_year,_month))
          {
	      assert(false);
          }
	   }

       Date &operator=(const Date &d);

	 
  
       bool IsInvalid(); 
       bool isLeapYear(int year); 
       int GetMonthDay(int year, int month); 
       void Show(); 

       bool operator==(const Date& d); //判断相等
       bool operator!=(const Date& d);//判断不等
       bool operator>=(const Date& d);//大于等于
       bool operator<=(const Date& d);//小于等于
       bool operator>(const Date& d); //大于
// d1 < d2 
       bool operator<(const Date& d);  //小于
// d1 + 10 
		Date operator+(int day); 
		Date& operator+=(int day); 
		Date operator-(int day); 
		Date& operator-=(int day); 
		int operator-(const Date& d); 

		//++d1
		Date& operator++(); // 前置 
		//d1++
		Date operator++(int); // 后置 
		Date& operator--(); //前置
		Date operator--(int);//后置


private: 
		int _year; 
		int _month; 
		int _day; 
}; 



bool Date::operator==(const Date& d)//判断相等
{
	if((_year == d._year)&&(_month ==d._month)&&(_day == d._day))
          return true;
	else
		return false;
}

bool Date:: operator<(const Date&d)//判断小于
 {
     if ((d._year<_year)
         ||(d._year==_year&&d._month<_month)
         || (d._year==_year&&d._month==_month&&d._day<_day))
     {
             return false;
     }
     return true;
}
bool Date::operator != (const Date & d)//判断不等于
{
	return !(*this == d);
}
bool Date:: operator>=(const Date& d)//大于等于调小于的复用
{
    return !(*this<d);
}
bool Date::operator<=(const Date& d)//小于等于调用小于和等于的复用
{
    return (*this<d || *this == d);
}
bool Date::operator>(const Date& d)//大于调用小于等于的复用
{
    return !(*this <= d);
}

int Date::GetMonthDay(int year,int month)//获取当月天数
{
	assert(month>0 && month <13);
	static int monthday[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
	int day=monthday[month];

    if(month == 2 &&isLeapYear(year))
	{
		day+=1;
	}
	return day;

}

//bool Date::IsInvalid()//判断值是否合法
//{
//	if((month<0) ||(month>12)||((day<0)||(day>31)
//            return false;
//}

bool Date:: isLeapYear(int year)//判断是否是闰年
{
	if((year%4==0) && (year %100 !=0 )||(year%400==0))
		return true;
	else
		return false;
}

void Date::Show()
{
	cout<<_year<<"/"<<_month<<"/"<<_day<<endl;
}



Date Date:: operator+(int day)//日期加天数
{
	if(day<0)
	{
		return *this-(-day);
	}
	Date ret(*this);
	ret._day+=day;

	while(ret._day >GetMonthDay(ret._year,ret._month))
	{
		ret._day-=GetMonthDay(ret._year,ret._month);
		ret._month++;
		if(ret._month ==13)
		{
			ret._year++;
			ret._month=1;
		}
	}
    return ret;
}


Date& Date::operator+=(int day)//减少一次拷贝构造
{
	*this=*this+day;
	return *this;
}
Date Date::operator -(int day)
{
	if(day<0)
	{
		return *this + (-day);
	}
     Date ret(*this);
     ret._day-= day;
     while(ret._day<0)
	{       ret._month--;
 		
  		if(ret._month == 0)
 		{
		ret._year--;
 		ret._month=12;
 		}
		ret._day+=GetMonthDay(ret._year,ret._month);
 	}
	return ret;
}

Date& Date::operator -=(int day)//日期减等
{
	return (*this -= day);
}

Date& Date::operator =(const Date &d)
{
	if((*this)!=d)
	{
		this->_year=d._year;
		this->_month=d._month;
		this->_day=d._day;
	}
	return (*this);
}


int Date::operator -(const Date &d)//一个日期减去另一个日期
{
	Date max= *this;Date min=d;
	int flag=1;
	if((*this)<d)
	{
		max=d;
		min=*this;
		flag=-1;
	}
	int day=0;
	while(min<=max)
	{
		min++;
		day++;
	}
	return day*flag;
}



Date& Date::operator ++()
{
	*this=*this+1;
	return *this;
}

Date Date::operator ++(int)
{
	Date tmp(*this);
	*this=*this+1;
	return tmp;
}

Date& Date::operator --()
{
	*this=*this-1;
	return (*this);
}

Date Date::operator --(int)
{
	Date tmp(*this);
	*this=*this-1;
	return (tmp);
}

int main() 
{ 
	Date d1(2018,5,3);
    d1.Show();
    Date d2(2018,4,5);
    Date d3(2018 ,3,2);
    d2.Show();
    (d1 + 100).Show();
    (d1 +(- 4)).Show();
    (d1 - 100).Show();
    (d1).Show();
    --d1;
    d1.Show();
    (++d1).Show();
    
    d1=d2=d3;
   
    system("pause");

 

return 0; 
} 

结果

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值