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;
}

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
程序清单 按以下步骤向视图类(CClockView)添加下列数据成员及成员函数。 (1) 添加表示年、月、日、时、分、秒的变量。 int year; int month; int day; int hour; int minute; int second; (2) 添加秒表的计数变量。 int watch; (3) 添加时钟的画笔及画刷变量。 CPen m_HouPen, m_MinPen, m_SecPen; // 各种针的画笔 CBrush m_MarkBrush; // 表盘标记的画刷 (4) 添加时钟控制变量。 CPoint m_Center; // 表的中心 double m_Radius; // 表的半径 CPoint m_Hour [2], m_OldHour [2]; // 时针当前及前一次位置 CPoint m_Minute [2], m_OldMin [2]; // 分针当前及前一次位置 CPoint m_Second [2], m_OldSec [2]; // 秒针当前及前一次位置 (5) 添加秒表的两个按钮位置变量。 CRect m_WatchStart; CRect m_WatchStop; (6) 添加两个函数,计算时钟各指针位置。 void SetClock (int hour, int minute, int second); CPoint GetPoint (int nLenth, int nValue); (7) 在视图类构造函数中增加初始化语句: CClockView::~CClockView() { //设定时间 year=2010; month=11; day=22; hour=0; minute=0; second=0; //设定画笔画刷 m_HouPen.CreatePen(PS_SOLID,5,RGB(255,0,0));//时针画笔 m_MinPen.CreatePen(PS_SOLID,3,RGB(0,0,250));//分针画笔 m_SecPen.CreatePen(PS_SOLID,1,RGB(0,0,0));//秒针画笔 m_MarkBrush.CreateSolidBrush(RGB(250,250,0)); //设定表芯位置 m_Center.x=222; m_Center.y=222; //设定时钟半径 m_Radius=222; //计算指针位置 SetClock(hour,minute,second); //设定秒表计数器及按钮位置 watch=0; m_WatchStart=CRect(480,310,560,340);//启动按钮 m_WatchStop=CRect(590,310,670,340);//停止按钮 } 编写指针位置函数SetClock和GETpOINT。 首先在ClockView.cpp文件头部下添加下面两行代码,以便进行数学计算。 #define PI 3.14159265258 #include"math.h" 然后添加下列代码: //计算个指针位置的函数 void CClockView::SetClock(int hour,int minute,int second) { hour=hour*5; hour=hour+minute/12; //保存时针原位置 m_OldHour[0]=m_Hour[0]; m_OldHour[1]=m_Hour[1];

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值