C++实战项目:日期计算器的实现

近听水无声477 2024-08-22 10:35:02 阅读 95

前言

Hello,小伙伴们,经过了前面对C++基础知识的学习,我们今天就着重运用一下前面学习到的知识,来通过类和对象以及运算符重载的部分知识来实现,来完成我们的日期计算器。

日期计算器,顾名思义,就是可以通过日期和天数来进行年、月、日的转换、计算。

1.可以实现具体日期与天数的加减,并得到加减计算后的日期。

2.可以实现两个具体日期之间的加减,计算两日期之间相差的天数。

 功能不是特别的复杂,我们现在就可以着手尝试了。

好,按例三连上车不迷路,开始我们今天的内容。

在看这篇文章的时候,强烈推荐大家先看看我之前的这两篇文章,来学习一下C++类和对象的基础:

http://t.csdnimg.cn/OY9mJ

http://t.csdnimg.cn/ZK1sA

1.日期类的定义

首先我们要定义一个日期类,运用我们刚学习的C++知识,我们这里直接看代码:

案例,我们还是先创建3个文件来实现我们的目的

<code>#pragma once

#include<iostream>

#include<assert.h>

class Date

{

public:

Date(int year = 2024, int month = 8, int day = 16);

//~Date();

private:

int _year;

int _month;

int _day;

};

在这里,我们先来解决构造函数和析构函数的问题:

构造函数:

我们在Date.cpp文件中实现他的功能:

Date::Date(int year, int month, int day)

{

_year = year;

_month = month;

_day = day;

}

由于在日期类中,我们没有申请内存空间,也就是该类中不存在深度拷贝,因此我们就不需要自己单独实现析构函数。

 2.日期类的打印(DatePrint)

完成构造函数后,我们就可以通过打印函数来显示我们定义的日期类的值:

首先我们要完成日期打印函数的声明: 

#pragma once

#include<iostream>

#include<assert.h>

class Date

{

public:

Date(int year = 2024, int month = 8, int day = 16);

//~Date();

void DatePeint();//日期打印

private:

int _year;

int _month;

int _day;

};

 接下来我们来实现日期类打印函数的功能:

void Date::DatePrint()

{

cout << _year << "/" << _month << "/" << _day << endl;

}

接下来我们来展示一下这个函数的功能:

3.比较运算符的重载 

前面我们学习了运算符重载方面的知识,我们接下来就设计及应用一下:

比较运算符的种类有很多,但是在运算符重载上实现的方法基本一样,这里借用我们前面学到的知识很容易就能实现:

 

<code>#pragma once

#include<iostream>

#include<assert.h>

class Date

{

public:

Date(int year = 2024, int month = 8, int day = 16);

//~Date();

void DatePeint();//日期打印

//比较大小运算符的重载

bool operator==(Date& d);

bool operator!=(Date& d);

bool operator>(Date& d);

bool operator<(Date& d);

bool operator<=(Date& d);

bool operator>=(Date& d);

private:

int _year;

int _month;

int _day;

};

代码实现:

bool Date::operator==(Date& d)

{

return _year == d._day

&& _month == d._month

&& _day == d._day;

}

Date& Date::operator=(const Date& d1)

{

_year = d1._year;

_month = d1._month;

_day = d1._day;

return *this;

}

bool Date::operator!=(Date& d)

{

return !(*this == d);

}

bool Date::operator>(Date& d)

{

if (_year > d._year )

{

return true;

}

else if (_year == d._year && _month >d._month)

{

return true;

}

else if (_year == d._year && _month == d._month && _day > d._day)

{

return true;

}

return false;

}

bool Date::operator<(Date& d)

{

return !(*this >= d);

}

bool Date::operator<=(Date& d)

{

return *this < d || *this == d;

}

bool Date::operator>=(Date& d)

{

return *this > d || *this == d;

}

运算符重载的实现逻辑十分的灵活,我们只需要实现几种基本的运算符重载,其他的我们就能够根据已知的运算关系,并运用或且非的逻辑关系来实现其余的运算符重载。

 4.日期+= 和 +操作(日期加天数)的实现

首先我们还是先来定义这个运算符的重载:

 要实现日期与天数的加操作,我们就好要得到每个月的天数:

#pragma once

#include<iostream>

#include<assert.h>

class Date

{

public:

Date(int year = 2024, int month = 8, int day = 16);

//~Date();

void DatePeint();//日期打印

//比较大小运算符的重载

bool operator==(Date& d);

bool operator!=(Date& d);

bool operator>(Date& d);

bool operator<(Date& d);

bool operator<=(Date& d);

bool operator>=(Date& d);

//获取每个月的天数

int GetMonthDay(int year, int month)

{

assert(month >= 1 && month <= 12);

//因为这个数组会高频·的进行调用,所以使用静态数组就能极大地提高效率

static int MonthDay[13] = { -1, 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 MonthDay[month];

}

Date& operator+=(int day);//日期与天数的加运算

Date operator+(int day);

private:

int _year;

int _month;

int _day;

};

实现的逻辑也十分的简单,我们先来看看代码:

Date& 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;

}

Date Date::operator+(int day)

{

Date tmp = *this;

tmp += day;

return tmp;

}

接下来我们来看看效果

 

接下来,我们使用网上的日期运算器来验证一下答案是否正确:

 

 5.日期-=和 -操作(日期减天数)的实现

日期与天数的想减得到日期的算法和前面的相加算法也相似。

我们还是先来定义相减运算:

 

<code>#pragma once

#include<iostream>

#include<assert.h>

class Date

{

public:

Date(int year = 2024, int month = 8, int day = 16);

//~Date();

void DatePeint();//日期打印

//比较大小运算符的重载

bool operator==(Date& d);

bool operator!=(Date& d);

bool operator>(Date& d);

bool operator<(Date& d);

bool operator<=(Date& d);

bool operator>=(Date& d);

//获取每个月的天数

int GetMonthDay(int year, int month)

{

assert(month >= 1 && month <= 12);

//因为这个数组会高频·的进行调用,所以使用静态数组就能极大地提高效率

static int MonthDay[13] = { -1, 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 MonthDay[month];

}

Date& operator+=(int day);//日期与天数的加运算

Date operator+(int day);

Date& operator+=(int day);//日期与天数的减运算

Date operator+(int day);

private:

int _year;

int _month;

int _day;

};

减运算符重载的实现与加运算符的实现逻辑基本相同,我们直接看代码:

 

Date& Date::operator-=(int day)

{

if (day < 0)

{

return (*this += -day);

}

_day -= day;

while (_day <= 0)

{

_day += GetMonthDay(_year, _month);

_month--;

while (_month <= 0)

{

_year--;

_month = 12;

}

}

return *this;

}

Date Date::operator-(int day)

{

Date tmp = *this;

tmp -= day;

return tmp;

}

接下来我们来测试一下运行效果:

让我们用日期计算器来验算一下日期的计算结果是否正确:

 

6. 前置++(--)与后置++(--)

根据我们前面的基础知识,我们知道前置++(--)和后置++(--)的冲在式定义就是根据是否有参数来判断的,所以本质上他们的实现就与+=(-=)和-=(-) 相似。

首先来看定义:

<code>#pragma once

#include<iostream>

#include<assert.h>

class Date

{

public:

Date(int year = 2024, int month = 8, int day = 16);

//~Date();

void DatePeint();//日期打印

//比较大小运算符的重载

bool operator==(Date& d);

bool operator!=(Date& d);

bool operator>(Date& d);

bool operator<(Date& d);

bool operator<=(Date& d);

bool operator>=(Date& d);

//获取每个月的天数

int GetMonthDay(int year, int month)

{

assert(month >= 1 && month <= 12);

//因为这个数组会高频·的进行调用,所以使用静态数组就能极大地提高效率

static int MonthDay[13] = { -1, 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 MonthDay[month];

}

Date& operator+=(int day);//日期与天数的加运算

Date operator+(int day);

Date& operator-=(int day);//日期与天数的减运算

Date operator-(int day);

//前置和后置的区别就是看式子中是不是有参数

Date& operator++();

Date& operator++(int );

Date& operator--();

Date& operator--(int);

private:

int _year;

int _month;

int _day;

};

我们直接来代码:

Date& Date::operator++()

{

return (*this += 1);

}

Date& Date::operator++(int)

{

Date tmp(*this);

*this += 1;

return tmp;

}

Date& Date:: operator--()

{

return (*this -= 1);

}

Date& Date::operator--(int)

{

Date tmp(*this);

*this -= 1;

return tmp;

}

简单的来看看效果,单独看这个的用处好像是不大,但是结合到接下来我们要实现的功能,这个重载式就会发挥很大的作用:

7.两日期之间相差的天数 

 首先我们还是先来定义这个重载式:

#pragma once

#include<iostream>

#include<assert.h>

class Date

{

public:

Date(int year = 2024, int month = 8, int day = 16);

//~Date();

void DatePeint();//日期打印

//比较大小运算符的重载

bool operator==(Date& d);

bool operator!=(Date& d);

bool operator>(Date& d);

bool operator<(Date& d);

bool operator<=(Date& d);

bool operator>=(Date& d);

//获取每个月的天数

int GetMonthDay(int year, int month)

{

assert(month >= 1 && month <= 12);

//因为这个数组会高频·的进行调用,所以使用静态数组就能极大地提高效率

static int MonthDay[13] = { -1, 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 MonthDay[month];

}

Date& operator+=(int day);//日期与天数的加运算

Date operator+(int day);

Date& operator-=(int day);//日期与天数的减运算

Date operator-(int day);

//前置和后置的区别就是看式子中是不是有参数

Date& operator++();

Date& operator++(int );

Date& operator--();

Date& operator--(int);

//计算两个日期之间的天数差

int operator-(const Date& d);

private:

int _year;

int _month;

int _day;

};

大家在这个时候可以来想想,用什么方法能得到两个日期之间的天数差异:

想要实现这个方法其实十分的简单,我们先找到小的那个日期,再让这个日期++,记录他++的次数,直到他与那个较大的日期相等为止,记录得到的次数就是相差的天数。

接下来我们来实现一下代码:

int Date::operator-(const Date& d)

{

Date small =d ;

Date big = *this;

int flag = 1;

if (big < small)

{

big = d;

small = *this;

flag *= -1;

}

int count = 0;

while (small < big)

{

small++;

++count;

}

return (count - 1) * flag;

}

 我们实现了代码,接下来我们来测试一下代码的效果:

我们就简单测试一下从 8 月16号,到今年国庆节之间的天数差,然后我们就在网上的日期计算器上验算一下我们得结果:

8.代码展示

我们完成了日期计算器的, 接下来是代码展示:

Date.h

<code>#pragma once

#include<iostream>

#include<assert.h>

using namespace std;

class Date

{

public:

friend ostream& operator<<(ostream& out, const Date& d);

friend istream& operator>>(istream& out, Date& d);

Date(int year = 2024, int month = 8, int day = 16);

///~Date();

//日期值的打印

void DatePrint();

//赋值运算符的重载

Date& operator=(const Date& d1);

//比较大小运算符的重载

bool operator==(Date& d);

bool operator!=(Date& d);

bool operator>(Date& d);

bool operator<(Date& d);

bool operator<=(Date& d);

bool operator>=(Date& d);

//获取每个月的天数

int GetMonthDay(int year, int month)

{

assert(month >= 1 && month <= 12);

//因为这个数组会高频·的进行调用,所以使用静态数组就能极大地提高效率

static int MonthDay[13] = { -1, 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 MonthDay[month];

}

Date& operator+=(int day);

Date operator+(int day);

Date& operator-=(int day);

Date operator-(int day);

//前置++

Date& operator++();

Date& operator++(int );

Date& operator--();

Date& operator--(int);

//计算两个日期之间的天数差

int operator-(const Date& d);

bool CheckDate()

{

if (_month >= 13 || _month <= 0)

{

return false;

}

if (_day >= GetMonthDay(_year, _month)|| _day <= 0)

{

return false;

}

return true;

}

private:

int _year;

int _month;

int _day;

};

//ostream& operator<<(ostream& out, const Date& d);

//& operator>>(istream& out, const Date& d);

Date.cpp 

#define _CRT_SECURE_NO_WARNINGS 1

#include"Date.h"

Date::Date(int year, int month, int day)

{

_year = year;

_month = month;

_day = day;

if (!CheckDate())

{

cout << "输入非法日期!!" << "->";

cout << *this;

}

}

void Date::DatePrint()

{

cout << _year << "/" << _month << "/" << _day << endl;

}

bool Date::operator==(Date& d)

{

return _year == d._day

&& _month == d._month

&& _day == d._day;

}

Date& Date::operator=(const Date& d1)

{

_year = d1._year;

_month = d1._month;

_day = d1._day;

return *this;

}

bool Date::operator!=(Date& d)

{

return !(*this == d);

}

bool Date::operator>(Date& d)

{

if (_year > d._year )

{

return true;

}

else if (_year == d._year && _month >d._month)

{

return true;

}

else if (_year == d._year && _month == d._month && _day > d._day)

{

return true;

}

return false;

}

bool Date::operator<(Date& d)

{

return !(*this >= d);

}

bool Date::operator<=(Date& d)

{

return *this < d || *this == d;

}

bool Date::operator>=(Date& d)

{

return *this > d || *this == d;

}

Date& 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;

}

Date Date::operator+(int day)

{

Date tmp = *this;

tmp += day;

return tmp;

}

Date& Date::operator-=(int day)

{

if (day < 0)

{

return (*this += -day);

}

_day -= day;

while (_day <= 0)

{

_day += GetMonthDay(_year, _month);

_month--;

while (_month <= 0)

{

_year--;

_month = 12;

}

}

return *this;

}

Date Date::operator-(int day)

{

Date tmp = *this;

tmp -= day;

return tmp;

}

Date& Date::operator++()

{

return (*this += 1);

}

Date& Date::operator++(int)

{

Date tmp(*this);

*this += 1;

return tmp;

}

Date& Date:: operator--()

{

return (*this -= 1);

}

Date& Date::operator--(int)

{

Date tmp(*this);

*this -= 1;

return tmp;

}

int Date::operator-(const Date& d)

{

Date small =d ;

Date big = *this;

int flag = 1;

if (big < small)

{

big = d;

small = *this;

flag *= -1;

}

int count = 0;

while (small < big)

{

small++;

++count;

}

return (count - 1) * flag;

}

ostream& operator<<(ostream& out, const Date& d)

{

out << d._year << "年" << d._month << "月" << d._day << "日" << endl;

return out;

}

istream& operator>>(istream& in, Date& d)

{

cout << "请依次输入有效的年月日信息" << endl;

while (1)

{

in >> d._year >> d._month >> d._day;

if (d.CheckDate())

{

break;

}

cout << "日期非法!!" << "->";

cout << d;

}

return in;

}

Test.c 

#define _CRT_SECURE_NO_WARNINGS 1

#include"Date.h"

int main()

{

Date d1;

Date d2(2024, 10, 1);

d1.DatePrint();

d2.DatePrint();

cout << d2 - d1 << endl;

}

 好,今天的学习就到这里了,我们下期再见,拜拜!!!



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。