日期计算器

class Date
{
public:                //没用初始化列表
	Date(int year = 1999,int month = 1,int day = 1)//最好定义为全缺省 
	{
		//检查日期是否合法

		if(year < 1900
			|| month < 1 || month > 12
			|| day < 1 || day > GetMonthDay(year,month))
		{
			cout<<"非法日期"<<endl;

		}

		_year = year;
		_month = month;
		_day = day;
	}

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

	//d2 = d3  =>  d2.operator(&d2,d3)
	Date& operator=(const Date& d)     //有俩个参数,但只写一个,因为还有一个参数是隐含的this指针。
	{
		if(this != &d)          //是否是自己给自己赋值。没有什么很坏的影响,只是白做了而已。
		{
			this->_year = d._year;             //this可以显示的写出来,也可以不写,写着this在这里方便于观察。
			this->_month = d._month;
			this->_day = d._day;
		}
		return *this;   //赋值操作已经完成,为什么有个返回值?因为赋值运算符的重载支持三个数,i=j=k;k先赋给j后有一个返回值j,将这个返回值赋给i,返回的是同类型对象,所以类型为Date
		//但此时如果没有给函数类型加引用,就是传值返回,不会直接返回,会创建一个临时对象。。会多一次拷贝构造,拷贝一个临时对象,再拿这个临时对象做返回
		//传值返回:返回的是一个临时对象
		//传引用返回:返回的对象出了作用域还在
	}

	//d1 < d2  会先去全局区找有没有小于的运算符重载,没有的话就到类中找,找到了,其实就转化为->d1.operator<(&d1,d2)
	//bool operator<(const Date& x1)  //在类外面我们实现了第一次的operator,对类外进行改进
 //   {
	//	if(_year < x1._year)
	//	{
	//		return true;
	//	}
	//	else if(_year == x1._year)
	//	{
	//		if(_month < x1._month)
	//		{
	//			return true;
	//		}
	//		else if(_month == x1._month)
	//		{
	//			if(_day < x1._day)
	//				return true;
	//		}
	//	}
	//	return false;
 //   }

	//d1+10
	//Date operator+(int day)  //自己写的
	//{
	//	/*int day = day + _day;      
	//	while(day > GetMonthDay(_year,_month))
	//	{
	//		day = day - GetMonthDay(_year,_month);
	//		_month++;

	//		if(_month > 12)
	//		{
	//			_year++;
	//			_month = 1;
	//			_day = 1;
	//		}
	//	}
	//	return *this;*/
	//}

	//Date operator+(int day)      
	//{
	//	Date ret(*this);        //+运算符不能改变原有的this的值,所以需要一个临时变量和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;   //返回一个临时变量,所以用传值返回。
	//}
	////d1 += 10
	//Date& operator+=(int day)
	//{
	//	*this = *this + day;    //调一次+再调一次赋值
	//	return *this;     //这样的前提是先实现+,但是先实现+=好,因为+里既拷贝还要开空间还要赋值
	//}

	Date& operator+=(int day)
	{
		if(day < 0)
		{
			return *this -= -day;
		}
		_day += day;
		while(_day > GetMonthDay(_year,_month))
		{
			_day -= GetMonthDay(_year,_month);
			_month++;

			if(_month == 13)
			{
				_year++;
				_month = 1;
			}
		}
		return *this;
	}

	//d+10
	Date operator+(int day)
	{
		Date ret(*this);//*this 是d
		ret += day;

		return ret;
	}

	//自己写的
	/*Date operator-(int day)
	{
		Date ret(*this);
		
		ret._day = day - ret._day;
		while(ret._day > GetMonthDay(ret._year,ret._month))
		{
			ret._day = ret._day - GetMonthDay(ret._year,ret._month);
			ret._month--;

			if(ret._month == 0)
			{
				ret._year--;
				ret._month = 12;
			}
		}
		return ret;
	}
	Date& operator-=(int day)
	{
		*this = *this - day;
		return *this;
	}*/

	//上课
	/*Date operator-(int day)
	{
		Date ret(*this);

		ret._day -= day;
		while(ret._day <= 0)
		{
			ret._month--;
			ret._day += GetMonthDay(ret._year,ret._month);

			if(ret._month == 0)
			{
				ret._year--;
				ret._month = 12;
			}
		}
		return ret;
	}*/
	Date& operator-=(int day)
	{
		if(day < 0)
		{
			return *this += -day;
		}
		_day -= day;
		while(_day <= 0)
		{
			--_month;
			if(_month == 0)
			{
				_year--;
				_month = 12;
			}
			_day+=GetMonthDay(_year,_month);
		}
		return *this;
	}
	Date operator-(int day)
	{
		Date ret(*this);

		ret -= day;
		return ret;
	}
	//d1 -d2
	int operator-(const Date& d)     //不加const d2会被改
	{
		int flag = 1;
		Date max = *this;
		Date min = d;

		if(*this < d)
		{
			max = d;
			min = *this;
			flag = -1;
		}
		int day = 0;
		while(min < max)
		{
			++(min);
			++day;
		}
		return day*flag;
	}

	//++d  => d.operator++(&d)
	Date& operator++()    //前置   返回值是++后的值
	{
		*this += 1;
		return *this;
	}

	//d++  => operator++(&d,0)
	Date operator++(int)  //后置    int只是为了与前置做一个区分   返回的是++前的值
	{
		Date ret(*this);
		*this += 1;
		return ret;
	}

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


	bool operator>(const Date& d)
	{
		if(_year > d._year)
		{
			return true;
		}

		else if(_year == d._year)
		{
			if(_month > d._month)
			{
				return true;
			}
			else if(_month == d._month)
			{
				if(_day > d._day)
					return true;
			}
		}
		return false;
	}
	bool operator==(const Date& d)
	{
		return _year == d._year
			&& _month == d._month
			&&_day == d._day;
		 
	}
	bool operator>=(const Date& d)
	{
		return *this > d || *this == d;
	}
	bool operator<(const Date& d)
	{
		return !(*this >= d);
	}
	bool operator<=(const Date& d)
	{
		return !(*this > d);
	}
	bool operator!=(const Date& d)
	{
		return !(*this == d);
	}

	//~Date()         //这个日期类可以不去清理,但有的类需要清理,比如顺序表
	//{
	//	//清理工作
	//	cout<<"~Date()"<<endl;
	//}
	void Display()
	{
		cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
	}
	int GetMonthDay(int year,int month)
{
	 static int MonthDay[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
	 int day = MonthDay[month];
		 if(month == 2
			 && ((year%400 == 0) || (year%4 == 0 && year%100 != 0)))
		 {
			 day += 1;
		 }
		 return day;
}
private:
	int _year;
	int _month;
	int _day;
};

//bool operator<(const Date& x1,const Date& x2)  //要穿引用返回;如果传值虽然不会无穷递归,但传值代价大,要开辟空间还要调拷贝构造函数。
//	//并且比较完不会改变x1x2所以最好加一个const  //引用做参数提高效率,提高性能
//	//这个函数之所以完成,是因为吧成员变量定义为了公有,但公有会破坏C++封装性,可是定义为私有我这个函数就跑不了。。在类外不可访问,那就放在类中
//	//但直接放在类中又有错误:operator<的参数太多   
//{
//	if(x1._year < x2._year)
//	{
//		return true;
//	}
//	else if(x1._year == x2._year)
//	{
//		if(x1._month < x2._month)
//		{
//			return true;
//		}
//		else if(x1._month == x2._month)
//		{
//			if(x1._day < x2._day)
//				return true;
//		}
//	}
//	return false;
//}

void test()
{
	Date d1(2018,9,20);
	Date d2(2019,2,28);
	d2.Display();
	cout<<d2-d1<<endl;
	/*d1 = d2 - 20;
	d1.Display();

	(++d1).Display();
	(d1++).Display();
	(--d2).Display();
	(d2--).Display();*/
	//Date d2(2018,2,2);
	//
	// 
	//cout<<d1.operator<(d2)<<endl;  //(<<优先级高于<)
	////cout<<operator<(d1,d2)<<endl;  
	//d2 = d1;
	//d2.Display();
	//Date d2(2018,2,29);
}

猜你喜欢

转载自blog.csdn.net/hgelin/article/details/82799757