c++---模拟实现日期类

在学习了类和对象的之后大多数都含有一个疑惑,为什么要学习我们的class ?因为类封装了我们的属性和方法,不只是在我们写的时候更加具有我们的可读性,也会让代码更加具有访问控制的约束。
实现日期类,为什么要实现日期类,因为日期在我们的生活中随处可见,实现一个日期类只在使用的时候调用类以及类中的方法就好了,另一个原因是在常见的类型,比如数字等等都具有±*/等等的方法,但是日期类是我们自定义的类型,又怎样去实现日期类的加减呢?
运算符重载就能解决我们的问题,运算符重载时类为了解决自定义类型的运算,比如在一个类定义了之后会默认的生成一个赋值运算符的重载,
运算符重载关键字operator+需要重载的运算符

我们下面使用通过我们运算符的重载来实现我们的日期类
首先在类中需要含有三个我们的私有成员_day,_month,_year

  • 构造函数和析构函数,以及拷贝构造,赋值操作符都可以不用实现,因为我们这里不涉及深拷贝浅拷贝,不会造成一个内存多次释放的情况,使用编译器默认生成的就可以满足需求
  • 时间比较运算符的重载
	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;
  • +=、+、-、-=运算符重载
	Date operator-(int day) const;
	Date& operator-=(int day);
		Date& operator+=(int day);//
	Date operator+(int day) const;//+天数
  • ++,–
    这里++,–都会出现前置++和后置++,–同样也会出现,在这里我们为了区分使用一个占位符来区分前置和后置,在后置中加上int参数来占位
	Date& operator++();		// 前置++
	Date operator++(int);	// 后置++

	Date& operator--();		// 前置--
	Date operator--(int);    //后置--
  • “ -” 运算符
    这里和上面的不一样上面是减去一个天数,这里是Date-Date(两个类进行相减)。

可以说Date类麻雀虽小,但是五脏俱全,不仅仅对我们的类的构造函数,析构函数等等都有一定的领悟,同时包含运算符的重载。以及在代码中含有const和&。所以此类是我们需要学习的第一个class类

下面是代码,我会在代码中详细的进行注释方便学习
Date.h

#pragma  once
#include <iostream>
#include <assert.h>
using std::cout;
using std::endl;

class Date{
public:
	//得到一年的天数
	int getDays(int year) const {
		if (((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){
			return 366;
		}
		return 365;
	}
	//得到某年某月的天数,这里需要注意的是闰年的判断
	inline int GetMonthDay(int year, int month) const{
		static int monthArray[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))){
			return 29;
		}

		return monthArray[month];
	}
	//得到从现在打1900 1 1的天数,这里是为了方便计算日期-日期
	int GetDaysTo199011(Date d)const{
		int ret1 = 0;
		int i = 0;
		for (i = 1900; i < d._year; i++){
			ret1 += Date::getDays(i);
		}
		for (int j = 1; j < d._month; j++){
			ret1 += GetMonthDay(i, j);
		}
		ret1 += d._day - 1;
		return ret1;
	}
	//构造函数,是默认的构造函数,使用了全缺省的参数
	Date(int year=1900, int month=1, int day=1){
		if (year >= 1900
			&& month > 0 && month < 13
			&& day > 0 && day <= GetMonthDay(year, month)){
			_year = year;
			_month = month;
			_day = day;
		}
		else{
			//assert(false);
			cout << "非法日期" << endl;
		}
	}

	void Print(){
		cout << _year << "-" << _month << "-" << _day << endl;
	}
	//运算符的重载,这里加上const是因为比较的时候我们不会改变我们的Date值,&传递是因为减少一个拷贝构造
	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;

	//前置++和后置++是用占位符进行区分
	Date& operator++();		// 前置++
	Date operator++(int);	// 后置++
	Date& operator+=(int day);
	//这里的const是const成员函数,是修饰this指针的,是this指针不能被修改
	Date operator+(int day) const;//+天数

	Date& operator--();		// 前置--
	Date operator--(int);	// 后置--
	Date operator-(int day) const;
	Date& operator-=(int day);

	int operator-(const Date&d) const;
private:
	int _year;
	int _month;
	int _day;

};

在实现类中的方法的时候需要注意的是我们需要代码复用,不用每一个函数都自己去实现,可以依靠我们实现过的代码去实现其他的函数,比如比较运算符我们就可以指示线两个,例如实现了>和==。那么<=就是!>,其他都是类似。保持一个原则,尽量减少拷贝构造和代码的冗余。
Date.cpp

#include "Date.h"

Date& Date::operator++(){//前置++
	return *this += 1;
}
Date Date::operator++(int){//后置++
	Date ret = *this;//这是一个拷贝构造
	*this += 1;
	return ret;
}
Date Date::operator+(int day) const{//调用—>+=来计算
	Date ret = *this;
	ret += day;
	return ret;
}
Date& Date::operator+=(int day){
	if (day<0){
		day = -day;
		return *this -= day;
	}
	_day += day;
	while (_day > GetMonthDay(_year, _month)){
		_day -= GetMonthDay(_year, _month);
		_month++;
		if (_month == 13){
			_month = 1;
			_year++;
		}
	}
	return *this;
}
Date& Date::operator-=(int day){  //-=
	if (day < 0){
		day = 0 -day;
		return *this += day;
	}
	this->_day -= day;
	while (_day <= 0){
		_month--;
		if (_month == 0){
			_month = 12;
			_year--;
		}
		_day = _day + GetMonthDay(_year, _month);
	}
	return *this;
}

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

	Date ret = *this;
	*this -= 1;
	return ret;
}
bool Date::operator==(const Date& d) const{
	return (this->_year == d._year
		&& this->_month == d._month
		&&this->_day == d._day);
}
bool Date::operator<(const Date& d)const {
	if (this->_year < d._year){
		return true;
	}
	if (this->_year == d._year && this->_month < d._month){
		return true;
	}
	if (this->_year == d._year&&this->_month == d._month&&this->_day < d._day){
		return true;
	}
	return false;
}
bool Date::operator!=(const Date& d)const{
	return !(*this == d);
}
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);
}

//计算两个日期的减法
int Date::operator-(const Date&d) const{
	//计算一个日期到另一个日期相聚的天数
	return GetDaysTo199011(*this) - GetDaysTo199011(d);
}

建立main.cpp进行测试
main.cpp

#include "Date.h"

void test(){
	cout << "测试+= + 前置++ 后置++" << endl;
	Date d1(2012, 2, 5);
	Date d2(2036, 5, 6);
	(d1 + 10).Print();//测试+
	d2 += 20;//测试+=
	d2.Print();
	d2++.Print();//测试后置++
	(++d2).Print();//测试前置++
	cout << "测试-= - 前置-- 后置--" << endl;
	//测试-=
	Date d3(2018, 1, 1);
	cout << "aaaaa" << endl;
	d3 -= 1;
	d3.Print();
	//测试前置--和后置--和-
	Date d4 = d3 - 3;
	d4.Print();
	(--d4).Print();
	(d4--).Print();
	Date d5(2015, 1, 31);
	Date d6(2015, 2,1 );

	cout << "测试关系运算符" << endl;
	cout << "小于:"<<(d5 < d6) << endl;
	cout << "等于:"<<(d5 == d6) << endl;

	cout << (d5 - d6) << endl;

}
int main(){
	test();
	system("pause");
	return EXIT_SUCCESS;
}

会得到结果
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/boke_fengwei/article/details/90404095
今日推荐