在学习过C++的类和对象的知识后,我打算小小的尝试构建一下我的类,以用来熟悉与掌握类和对象的基本知识。下面内容以供参考使用。
一、日期类的构建
1.源文件
链接:https://pan.baidu.com/s/10XDXOMnNOW_czGdMIrFz1Q
提取码:lyjy
2.源文件的组成
(1)头文件.h
该文件用来存放库的引用,类的定义,成员函数、友元函数、变量的声明,以及宏定 义的声明,命名空间的展开。如下:
#pragma once //防止头文件被重复包含
#include<iostream>
#include<assert.h>
using namespace std;
class Date
{
public:
//构造函数
Date(int year = 1900, int month = 1, int day = 1);
// 拷贝构造函数
// d2(d1)
Date(const Date& d);
// 赋值运算符重载
// d2 = d3 -> d2.operator=(&d2, d3)
Date& operator=(const Date& d);
// 析构函数
~Date();
// 日期+=天数
Date& operator+=(int day);
// 日期+天数
Date operator+(int day);
// 日期-天数
Date operator-(int day);
// 日期-=天数
Date& operator-=(int day);
// 前置++
Date& operator++();
// 后置++
Date operator++(int);
// 后置--
Date operator--(int);
// 前置--
Date& operator--();
void Print();
int GetMonthDay(int year, int month);
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);
bool operator>(const Date& d);
//流提取
friend istream& operator>>(istream& in,Date& d);
//流插入
friend ostream& operator<<(ostream& out, const Date& d);
private:
int _year=0;
int _month=0;
int _day=0;
};
(2)函数文件.cpp
该文件用来存放函数的实现,使用#include“xxxx.h”作为自己的库。因为内容过多,仅 展示部分,如下:
#include"MyDT.h"
//构造函数
Date::Date(int year, int month, int day)
{
if ((month < 13 && month>0)&&(day>0&&day<=GetMonthDay(year,month)))
{
_year = year;
_month = month;
_day = day;
}
else
{
cout << "输入非法" << endl;
}
}
//拷贝构造函数
Date::Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
//流提取
istream& operator>>(istream& in, Date& d)
{
in >> d._year >> d._month >> d._day;
if (!((d._month < 13 && d._month>0) && (d._day > 0 && d._day <= d.GetMonthDay(d._year, d._month))))
{
cout << "输入非法" << endl;
assert(0);
}
return in;
}
//流插入
ostream& operator<<(ostream& out, const Date& d)
{
if (!((d._month < 13 && d._month>0) && (d._day > 0 && d._day <= d.GetMonthDay(d._year, d._month))))
{
cout << "输出非法" << endl;
}
else
{
out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
}
return out;
}
//获取该月的天数
int Date::GetMonthDay(int year, int month) const
{
assert(month > 0 && month < 13);
int arr[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
if (month == 2 && ((year % 4 == 0 && year != 0) || year % 400 == 0))
{
return 29;
}
else
{
return arr[month -1];
}
}
(3)测试文件.cpp
该文件为主函数main所在文件,主要是为了测试所构建的类是否可以正常使用,并使用一些测试用例来寻找bug。参考如下:
void test1()
{
/* Date d1(2023,3,2);
Date* d2 = &d1;
const Date* d3 = &d1;
cout << "d1:" << &d1 << endl;
cout <<"d2:" << d2 << endl;
cout <<"d3;" << d3 << endl*/;
Date d1;
Date d2(2022, 1, 4);
cin >> d1>>d2;
cout << d1<<d2;
}
int main()
{
test1();
return 0;
}
二、日期类的功能
介绍完了源文件的组成,那么现在我来介绍该日期类的功能。
实话实说,若该类用于工程项目,实在难登大雅之堂,因为我个人的测试用例毕竟不太全面。而个人娱乐使用,某些功能又显得太过冗余,所以下面我主要介绍该类的几种可能用到的功能。
1.日期+天数
应用场景:获取该日期几天后的日期,用来方便规划日程。
// 日期+=天数
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)
{
_month = 1;
_year++;
}
}
return *this;
}
//日期+天数
Date operator+(int day)
{
Date tmp(*this);
if (day < 0)
{
return tmp = tmp - (-day);
}
tmp._day += day;
while (tmp._day > GetMonthDay(tmp._year, tmp._month))
{
tmp._day -= GetMonthDay(tmp._year, tmp._month);
tmp._month++;
if (tmp._month > 13)
{
tmp._month = 1;
tmp._year++;
}
}
return tmp;
}
调用:
2.日期-天数
应用场景:获取该日期几天前的日期,用来回忆或记录。
// 日期-=天数
Date& operator-=(int day)
{
if (day < 0)
{
return *this+=(-day);
}
_day -= day;
while (_day <= 0)
{
_month--;
if (_month == 0)
{
_month = 12;
_year--;
}
_day += GetMonthDay(_year, _month);
}
return *this;
}
//日期-天数
Date Date::operator-(int day)
{
Date tmp(*this);
if (day < 0)
{
return tmp = tmp + (-day);
}
tmp._day -= day;
while (tmp._day < 0)
{
tmp._month--;
if (tmp._month == 0)
{
tmp._month = 12;
tmp._year--;
}
tmp._day += GetMonthDay(tmp._year, tmp._month);
}
return tmp;
}
调用:
3.日期-日期
应用场景:可以算从出生至今日一共存活了多少天数、距离节日、高考、考研、纪念日等 日期还相差多少天数。
// 日期-日期
int operator-(const Date& d)
{
Date maxtmp(*this);
Date mintmp(d);
int sum = 0;
int tag = 1;//标记正负天数
if (*this < d)
{
maxtmp = d;
mintmp = *this;
tag = -1;
}
while (maxtmp != mintmp)
{
if (maxtmp._year > mintmp._year)
{
maxtmp._month--;
if (maxtmp._month == 0)
{
maxtmp._month = 12;
maxtmp._year--;
}
sum += GetMonthDay(mintmp._year, maxtmp._month);
}
else if(maxtmp._month> mintmp._month)
{
maxtmp._month--;
sum += GetMonthDay(mintmp._year, maxtmp._month);
}
else
{
int dy =maxtmp._day- mintmp._day;
sum+= dy;
mintmp += dy;
}
}
return sum*tag;
}
调用:
4.获取当月天数
应用场景:方便上面三种函数的运行,并且便于自己知晓当月天数,尤其2月的天数。
int GetMonthDay(int year, int month) const
{
assert(month > 0 && month < 13);
int arr[12] = {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;
}
else
{
return arr[month -1];
}
}
调用:
三、总结
该类仅适合用于一些特殊场合,算是有些聊胜于无,但是对我这种初学C++的新手来说,十分有着锻炼的价值。