【C++】日期类

鼠鼠实现了一个日期类,用来练习印证前几篇博客介绍的内容!!

目录

1.日期类的定义 

2.得到某年某月的天数

 3.检查日期是否合法

 4.(全缺省)构造函数

5.拷贝构造函数 

6.析构函数

7.赋值运算符重载 

8.>运算符重载 

9.==运算符重载

 10.>=运算符重载

11.<运算符重载 

12.<=运算符重载 

13.!=运算符重载 

14.日期 += 天数 

15.日期+天数 

16.日期-=天数

17.日期-天数

18.前置++

19.后置++

20.前置-- 

21.后置--

22.日期-日期,返回天数 

 23.流插入运算符重载

24.流提取运算符重载 

25.test 


本鼠创建一个工程,工程包含三个文件,分别是Date.h、Date.cpp和test.cpp。 

1.日期类的定义 

本鼠对日期类的定义如下,放在了Date.h文件中:

class Date
{int _year;int _month;int _day;
public:inline int GetMonth_day()const//得到某年某月的天数{const int a[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };if (this->_month == 2 && (this->_year % 4 == 0 && this->_year % 100 != 0 || this->_year % 400 == 0)){return 29;}return a[this->_month];}bool Check()const;//检查日期是否合法Date(int year = 1, int month = 1, int day = 1);//(全缺省)构造函数Date(const Date& d);//拷贝构造函数~Date();//析构函数Date& operator=(const Date& d)//赋值运算符重载{this->_year = d._year;this->_month = d._month;this->_day = d._day;}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);//日期+=天数Date operator+(int day)const;//日期+天数Date& operator-=(int day);//日期-=天数Date operator-(int day)const;//日期-天数Date& operator++();//前置++Date operator++(int);//后置++Date& operator--();//前置--Date operator--(int);//后置--int operator-(const Date& d)const;//日期-日期,返回天数friend ostream& operator<<(ostream& cout, const Date& d);//友元函数:流插入运算符重载friend istream& operator>>(istream& cin, Date& d);//友元函数:流提取运算符重载
};

本鼠对于成员函数大部分都采取声明和定义分离的方式。成员变量无非就是年、月、日呗。还运用了友元的知识。如上代码所示。

2.得到某年某月的天数

 对于这个日期类所要实现的成员函数中有很多场景我们需要得到某年某月的天数,所以我们将这个功能实现成函数。又因为需要频繁调用这个函数,我们将他实现成内联函数。

声明和定义:

inline int GetMonth_day()const//得到某年某月的天数{const int a[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };if (this->_month == 2 && (this->_year % 4 == 0 && this->_year % 100 != 0 || this->_year % 400 == 0)){return 29;}return a[this->_month];}

注意:

  • 该函数的实现思路过于简单,本鼠就不解释了!
  • 内联函数声明和定义不可分离,又因为日期类的成员函数需频繁调用这个函数,所以我们将其声明和定义都实现在类里面。
  • 这是一个对this指针指向对象的成员变量只进行读访问的函数,所以我们将其实现成const成员函数。

 3.检查日期是否合法

例如构造函数可能构造了非法的日期,所以我们将检查日期是否合法这个功能实现成函数。

定义:

bool Date::Check()const//检查日期是否合法
{if (this->_year < 0 ||this->_month < 0 || this->_month > 12 ||this->_day<0 || this->_day>GetMonth_day()){return true;}return false;
}

注意:

  • 该函数的实现思路:我们这个日期类不支持公元前的年份。所以当this指针指向对象的日期:年小于0、月小于0、月大于12、日小于0、日大于该日期应得天数这几项但凡有一项为真时,说明日期非法,返回真;否则,返回假。
  • 该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 这是一个对this指针指向对象的成员变量只进行读访问的函数,所以我们将其实现成const成员函数。

 4.(全缺省)构造函数

我们分析日期类对象的初始化需求,若使用编译器生成的默认构造函数是达不到需求的,所以我们自己显式实现构造函数。

定义:

Date::Date (int year , int month , int day )//(全缺省)构造函数
{this->_year = year;this->_month = month;this->_day = day;if (Check()){cout << "构造了日期非法:" << *this << endl;}
}

注意:

  • 该函数的实现思路无非就是将第2、3、4个形参的年、月、日初始化this指针指向对象的成员变量(年、月、日),若形参没有接收到实参的拷贝,使用缺省值。
  • 需要检查this指针指向对象的日期是否合法。
  • 该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 缺省参数不能在函数声明和定义中同时出现,当函数声明和定义分离时在声明给缺省参数 。
  • 这是一个对this指针指向对象的成员变量要进行读写访问的成员函数,不能实现成const成员函数。

5.拷贝构造函数 

这个日期类不涉及资源申请,其实不用我们显式实现拷贝构造函数,用编译器生成的默认拷贝构造函数就行 ,本鼠显式实现就是练练手。

定义:

Date::Date(const Date& d)//拷贝构造函数
{this->_year = d._year;this->_month = d._month;this->_day = d._day;
}

注意:

  • 该函数的实现思路:第一个形参是隐藏的this指针,第二个形参是已存在对象的引用。 用第二个形参的成员变量初始化this指针指向的正在创建对象的成员变量。
  • 该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 这是一个对this指针指向对象的成员变量要进行读写访问的成员函数,不能实现成const成员函数。

6.析构函数

这个日期类的析构函数其实也不用我们自己显式实现的,练练手。

定义:

Date::~Date()//析构函数
{this->_year = this->_month = this->_day = 0;
}

注意:

  • ​​​不妨将this指针指向对象的成员变量赋值成0就行 ,其实函数体内为空也无妨。反正这个日期类没有申请资源,当对象生命周期结束后系统会将其内存收归就行。
  • 该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 这是一个对this指针指向对象的成员变量要进行读写访问的成员函数,不能实现成const成员函数。

7.赋值运算符重载 

其实这个函数也不用我们自己显式实现的,练练手。

 声明和定义:

	Date& operator=(const Date& d)//赋值运算符重载{this->_year = d._year;this->_month = d._month;this->_day = d._day;return *this;}

注意:

  • 该函数实现思路:第二个形参是已存在对象的引用。用第二个形参的成员变量赋值给this指针指向对象的成员变量就行。
  • 为了支持连续赋值,需要返回左操作数本身(拷贝也行)。
  • 赋值运算符只能重载成类的成员函数不能重载成全局函数。
  • 这是一个对this指针指向对象的成员变量要进行读写访问的成员函数,不能实现成const成员函数。

8.>运算符重载 

定义:

bool Date::operator>(const Date& d)const//>运算符重载
{if (this->_year > d._year){return true;}else if (this->_year == d._year){if (this->_month > d._month){return true;}else if (this->_month == d._month){return this->_day > this->_day;}}return false;
}

注意:

  • 该函数的第一个形参this指针为第一个操作数的地址,第二个形参为第二个操作数的引用。
  • 该函数的实现思路:若第一个操作数的年大于第二个操作数的年,返回真;若第一个操作数的年等于第二个操作数的年,那就若第一个操作数的月大于第二个操作数的月,返回真;若第一个操作数的年和月都等于第二个操作数的年和月,那就若第一个操作数的日大于第二个操作数的日,返回真;其余情况都返回假。
  • 该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 这是一个对this指针指向对象的成员变量只进行读访问的函数,所以我们将其实现成const成员函数。

9.==运算符重载

定义:

bool Date::operator==(const Date& d)const//==运算符重载
{return this->_year == d._year && this->_month == d._month && this->_day == d._day;
}

注意: 

  •  该函数的第一个形参this指针为第一个操作数的地址,第二个形参为第二个操作数的引用。
  • 该函数实现思路:第一个操作数的年、月、日都等于第二个操作数的年、月、日,返回真;否则,返回假。
  • 该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 这是一个对this指针指向对象的成员变量只进行读访问的函数,所以我们将其实现成const成员函数。

 10.>=运算符重载

定义:

bool Date:: operator>=(const Date& d)const//>=运算符重载
{return *this > d || *this == d;
}

注意: 

  •  该函数的第一个形参this指针为第一个操作数的地址,第二个形参为第二个操作数的引用。
  • 该函数的实现思路:若第一个操作数大于或者等于第二个操作数(调用>运算符重载和==运算符重载),返回真;否则,返回假。
  • 该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 这是一个对this指针指向对象的成员变量只进行读访问的函数,所以我们将其实现成const成员函数。

11.<运算符重载 

定义:

bool Date::operator<(const Date& d)const//<运算符重载
{return !(*this >= d);
}

 注意:

  • 该函数的第一个形参this指针为第一个操作数的地址,第二个形参为第二个操作数的引用。
  • 该函数的实现思路:返回>=运算符重载的逻辑取反就好。
  • 该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 这是一个对this指针指向对象的成员变量只进行读访问的函数,所以我们将其实现成const成员函数。

12.<=运算符重载 

定义:

bool Date::operator<=(const Date& d)const//<=运算符重载
{return !(*this > d);
}

注意:

  • 该函数的第一个形参this指针为第一个操作数的地址,第二个形参为第二个操作数的引用。
  • 该函数的实现思路:返回>运算符重载的逻辑取反就好。
  • 该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 这是一个对this指针指向对象的成员变量只进行读访问的函数,所以我们将其实现成const成员函数。

13.!=运算符重载 

定义:

bool Date::operator!=(const Date& d)const//!=运算符重载
{return !(*this == d);
}

注意:

  • 该函数的第一个形参this指针为第一个操作数的地址,第二个形参为第二个操作数的引用。
  • 该函数的实现思路:返回==运算符重载的逻辑取反就好。
  • 该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 这是一个对this指针指向对象的成员变量只进行读访问的函数,所以我们将其实现成const成员函数。

14.日期 += 天数 

这个函数本鼠想要的是日期+天数后,日期本身发生改变形成新日期并返回。 

定义:

Date& Date::operator+=(int day) //日期 += 天数
{this->_day += day;while (this->_day > GetMonth_day()){this->_day -= GetMonth_day();this->_month++;if (this->_month > 12){this->_month = 1;this->_year++;}}return *this;
}

注意:

  • 该函数的实现思路: this指针指向对象的日期的日+=天数。循环:日若超过“当年当月”该有的天数,说明月该+1;就让日-“当年当月”该有的天数,并++月;若是月超过12,年份就该+1;…………直到日小于“当年当月”该有的天数循环停止。思想本质就跟我们做加法运算是一样的,有时又要向高位进位。。
  • 该函数的返回值*this出了该函数作用域还存在,可以用引用返回。
  • 该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 这是一个对this指针指向对象的成员变量要进行读写访问的成员函数,不能实现成const成员函数。

15.日期+天数 

这个函数本鼠想要的是日期+天数后,日期本身不发生改变,却要返回日期+天数后的结果。

定义:

Date Date::operator+(int day)const//日期+天数
{Date tmp = *this;tmp += day;return tmp;
}

注意:

  • 该函数的实现思路:通过拷贝构造函数创建一个与this指针指向对象一样的临时对象,让临时对象+=天数,返回临时对象就好了。
  • 该函数的返回值是临时对象,出了该函数的作用域就不存在了,所以不能用引用返回。
  • 该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 这是一个对this指针指向对象的成员变量只进行读访问的函数,所以我们将其实现成const成员函数。

16.日期-=天数

这个函数本鼠想要的是日期-天数后,日期本身发生改变形成新日期并返回。 

定义:

Date& Date::operator-=(int day)//日期-=天数
{this->_day -= day;while (this->_day <= 0){this->_month--;if (this->_month < 1){this->_year--;this->_month = 12;}this->_day += GetMonth_day();}return *this;
}

注意:

  • 该函数的实现思路:this指针指向对象的日-=天数。循环:日若小于或等于0,说明月该-1;月--后需要判断月是否小于1,如果月小于1,年份就该-1;日+=“当年当月”该有的天数;…………直到日大于0循环停止。思想本质跟我们做减法运算是一样的,有时候要跟高位借位呗。。
  • 该函数的返回值*this出了该函数作用域还存在,可以用引用返回。
  • 该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 这是一个对this指针指向对象的成员变量要进行读写访问的成员函数,不能实现成const成员函数。

17.日期-天数

这个函数本鼠想要的是日期-天数后,日期本身不发生改变,却要返回日期-天数后的结果。

定义:

Date Date::operator-(int day)const//日期-天数
{Date tmp = *this;tmp -= day;return tmp;
}
  • 该函数的实现思路:通过拷贝构造函数创建一个与this指针指向对象一样的临时对象,让临时对象-=天数,返回临时对象就好了。
  • 该函数的返回值是临时对象,出了该函数的作用域就不存在了,所以不能用引用返回。
  • 该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 这是一个对this指针指向对象的成员变量只进行读访问的函数,所以我们将其实现成const成员函数。

18.前置++

前置++:日期本身+1,返回日期+1之后的结果。

定义:

Date& Date::operator++()//前置++
{*this += 1;return *this;
}

注意:

  • 这个函数实现思想过于简单,不解释了。
  •  该函数的返回值*this出了该函数作用域还存在,可以用引用返回。
  • 该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 这是一个对this指针指向对象的成员变量要进行读写访问的成员函数,不能实现成const成员函数。

19.后置++

后置++:先使用后+1,因此需要返回+1之前的旧值。日期本身+1,返回日期+1之前的旧日期。

定义:

Date Date::operator++(int)//后置++
{Date tmp = *this;*this += 1;return tmp;
}

注意:

  • 这个函数实现思想过于简单,不解释。
  • 后置++重载时多增加一个int类型的参数,不显式调用函数时该参数不用传递,编译器自动传递;显式调用该函数,那么一定要传入一个任意int整形以区分前置++。
  • 这个函数的返回值是临时变量,出了该函数作用域就不存在了,所以不能用引用返回。
  •  该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 这是一个对this指针指向对象的成员变量要进行读写访问的成员函数,不能实现成const成员函数。

20.前置-- 

前置--:日期本身-1,返回日期-1之后的结果。

定义:

Date& Date::operator--()//前置--
{*this -= 1;return *this;
}

注意:

  • 这个函数实现思想过于简单,不解释了。
  •  该函数的返回值*this出了该函数作用域还存在,可以用引用返回。
  • 该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 这是一个对this指针指向对象的成员变量要进行读写访问的成员函数,不能实现成const成员函数。

21.后置--

后置--:先使用后-1,因此需要返回-1之前的旧值。日期本身-1,返回日期-1之前的旧日期。

定义:

Date Date::operator--(int)//后置--
{Date tmp = *this;*this -= 1;return tmp;
}

注意:

  • 这个函数实现思想过于简单,不解释。
  • 后置--重载时多增加一个int类型的参数,不显式调用函数时该参数不用传递,编译器自动传递;显式调用该函数,那么一定要传入一个任意int整形以区分前置--。
  • 这个函数的返回值是临时变量,出了该函数作用域就不存在了,所以不能用引用返回。
  •  该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 这是一个对this指针指向对象的成员变量要进行读写访问的成员函数,不能实现成const成员函数。

22.日期-日期,返回天数 

这个函数本鼠想要获取日期之间夹杂着多少天呗。如果第一个日期大于第二个日期,返回的天数是负数;反之,为正数。

定义:

int Date::operator-(const Date& d)const//日期-日期,返回天数
{Date max = *this;Date min = d;int flag = -1;if (max < min){flag = 1;max = d;min = *this;}int n = 0;while (max != min){min++;n++;}return n * flag;
}

注意: 

  • 这个函数实现思路简单,本鼠就不解释了。
  •  该函数声明和定义分离,所以定义成员函数时,成员函数名前需要加Date::,成员函数定义在Date.cpp文件中。
  • 这是一个对this指针指向对象的成员变量只进行读访问的函数,所以我们将其实现成const成员函数。

 23.流插入运算符重载

介绍流插入运算符重载之前,我们需要回顾这里C++的输入&&输出介绍过的知识:cout是库里面的ostream类型的全局对象。

对于流插入运算符重载,本鼠并没有将其重载成日期类的成员函数,而是重载成全局函数,为啥?


我们先看流插入运算符一般的使用场景如下:

#include<iostream>
using namespace std;
int main()
{int a = 10;int b = 20;cout << a << ' ' << b << endl;return 0;
}

我们分析:

  • 分析1:对于流插入操作符<<来说,是有两个操作数的,第一个应该对象cout,第二个是需要“流向”控制台的对象
  • 分析2:流插入操作符<<需要支持连续输出,如这里:
cout << a << ' ' << b << endl;

这句语句的结合性是从左往右的,cout<<a的返回值是对象cout,这个返回值cout又作为cout<<' '的左操作数,cout<<' '的返回值又是对象cout,这个返回值cout又作为cout<<b的左操作数…………

如果我们将流插入运算符重载重载成日期类的成员函数的话,我们想想当我们在主函数调用的情景必然是这样的:

int main()
{Date d1;d1.operator<<(cout);//显式调用d1. << cout;//不显式调用return 0;
}

可是这样子的话代码的可读性不好,好像是cout通过<<“流向” d1一样。不符合我们对分析1的分析。


那该如何是好呢?其中一个办法就是将流插入运算符重载重载成全局函数。

那么将其重载成全局函数的话,也采用声明和定义分离,为了支持连续输出,返回值应该是对象cout。

声明,声明在Date.h文件中:

ostream& operator<<(ostream& cout, const Date& d);//流插入运算符重载

定义,定义在Date.cpp文件中:

ostream& operator<<(ostream& cout, const Date& d)//流插入
{cout << d._year << '/' << d._month << '/' << d._day ;return cout;
}

我们没有将其重载成全局函数,日期类的成员变量又是被访问限定符private修饰的,那么在这个全局函数中无权访问对象的成员变量啊。所以我们在日期类中用到友元函数:

friend ostream& operator<<(ostream& cout, const Date& d);//友元函数:流插入运算符重载

24.流提取运算符重载 

 介绍流提取运算符重载之前,我们需要回顾这里C++的输入&&输出介绍过的知识:cin是库里面的istream类型的全局对象。

流提取运算符重载的问题和流插入运算符重载的问题差不多,不介绍了。

流提取运算符重载重载成全局函数,采取声明和定义分离,为了支持连续输入,返回值应该是对象cin。

声明,声明在Date.h文件中:

ostream& operator<<(ostream& cout, const Date& d);//流插入运算符重载

定义,定义在Date.cpp文件中:

istream& operator>>(istream& cin,  Date& d)//流提取{cout << "请输入日期并以回车键结束" << endl;while (1){cin >> d._year >> d._month >> d._day;if (d.Check()){cout << "输入日期非法" << endl;}else{break;}}return cin;}

不同的是,这里流提取可以给一定的提示,如:请输入日期并以回车键结束。检查输入的日期是否合法也是必须的。

日期类中用到友元函数:

friend istream& operator>>(istream& cin, Date& d);//友元函数:流提取运算符重载

25.test 

 全部代码如下,可以在test.cpp中测试代码,有兴趣可以玩玩。

Date.h:

#pragma once
#include<stdbool.h>
#include<iostream>
using namespace std;
class Date
{int _year;int _month;int _day;
public:inline int GetMonth_day()const//得到某年某月的天数{const int a[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };if (this->_month == 2 && (this->_year % 4 == 0 && this->_year % 100 != 0 || this->_year % 400 == 0)){return 29;}return a[this->_month];}bool Check()const;//检查日期是否合法Date(int year = 1, int month = 1, int day = 1);//(全缺省)构造函数Date(const Date& d);//拷贝构造函数~Date();//析构函数Date& operator=(const Date& d)//赋值运算符重载{this->_year = d._year;this->_month = d._month;this->_day = d._day;return *this;}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);//日期+=天数Date operator+(int day)const;//日期+天数Date& operator-=(int day);//日期-=天数Date operator-(int day)const;//日期-天数Date& operator++();//前置++Date operator++(int);//后置++Date& operator--();//前置--Date operator--(int);//后置--int operator-(const Date& d)const;//日期-日期,返回天数friend ostream& operator<<(ostream& cout, const Date& d);//友元函数:流插入运算符重载friend istream& operator>>(istream& cin, Date& d);//友元函数:流提取运算符重载
};ostream& operator<<(ostream& cout, const Date& d);//流插入运算符重载istream& operator>>(istream& cin,  Date& d);//流提取运算符重载

Date.cpp:

#include"Date.h"
bool Date::Check()const//检查日期是否合法
{if (this->_year < 0 ||this->_month < 0 || this->_month > 12 ||this->_day<0 || this->_day>GetMonth_day()){return true;}return false;
}Date::Date (int year , int month , int day )//(全缺省)构造函数
{this->_year = year;this->_month = month;this->_day = day;if (Check()){cout << "构造了日期非法:" << *this << endl;}
}Date::Date(const Date& d)//拷贝构造函数
{this->_year = d._year;this->_month = d._month;this->_day = d._day;
}Date::~Date()//析构函数
{this->_year = this->_month = this->_day = 0;
}bool Date::operator>(const Date& d)const//>运算符重载
{if (this->_year > d._year){return true;}else if (this->_year == d._year){if (this->_month > d._month){return true;}else if (this->_month == d._month){return this->_day > this->_day;}}return false;
}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//>=运算符重载
{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);
}bool Date::operator!=(const Date& d)const//!=运算符重载
{return !(*this == d);
}Date& Date::operator+=(int day) //日期 += 天数
{this->_day += day;while (this->_day > GetMonth_day()){this->_day -= GetMonth_day();this->_month++;if (this->_month > 12){this->_month = 1;this->_year++;}}return *this;
}Date Date::operator+(int day)const//日期+天数
{Date tmp = *this;tmp += day;return tmp;
}Date& Date::operator-=(int day)//日期-=天数
{this->_day -= day;while (this->_day <= 0){this->_month--;if (this->_month < 1){this->_year--;this->_month = 12;}this->_day += GetMonth_day();}return *this;
}Date Date::operator-(int day)const//日期-天数
{Date tmp = *this;tmp -= day;return tmp;
}Date& Date::operator++()//前置++
{*this += 1;return *this;
}Date Date::operator++(int)//后置++
{Date tmp = *this;*this += 1;return tmp;
}Date& Date::operator--()//前置--
{*this -= 1;return *this;
}Date Date::operator--(int)//后置--
{Date tmp = *this;*this -= 1;return tmp;
}int Date::operator-(const Date& d)const//日期-日期,返回天数
{Date max = *this;Date min = d;int flag = -1;if (max < min){flag = 1;max = d;min = *this;}int n = 0;while (max != min){min++;n++;}return n * flag;
}ostream& operator<<(ostream& cout, const Date& d)//流插入
{cout << d._year << '/' << d._month << '/' << d._day ;return cout;
}istream& operator>>(istream& cin,  Date& d)//流提取{cout << "请输入日期并以回车键结束" << endl;while (1){cin >> d._year >> d._month >> d._day;if (d.Check()){cout << "输入日期非法,请重新输入" << endl;}else{break;}}return cin;}

test.cpp:

#include"Date.h"
int main()
{Date d1(2003, 12, 12);Date d2 = d1;cout << d1 << endl << d2 << endl;cout << (d1 > d2) << endl;cout << (d1 >= d2) << endl;cout << (d1 < d2) << endl;cout << (d1 <= d2) << endl;cout << (d1 == d2) << endl;cout << (d1 != d2) << endl;Date d3;cout << d3 << endl;cin >> d3 >> d2 >> d1;cout << d3 <<endl<< d2 <<endl<< d1 << endl;return 0;
}

 运行结果,符合预期:

 感谢阅读!!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/369480.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

有人物联的串口服务器USR-TCP232-410S基本测试通信和使用方案(485串口和232串口)

1.将 410S(USR-TCP232-410S&#xff0c;简称 410S 下同)的串口通过串口线(或USB 转串口线)与计算机相连接&#xff0c;通过网线将 410S 的网口 PC 的网口相连接&#xff0c;检测硬件连接无错误后&#xff0c;接入我们配送的电源适配器&#xff0c;给 410S 供电。观察指示灯状态…

jmeter-beanshell学习2-beanshell断言

继续写&#xff0c;之前写了获取变量&#xff0c;设置变量&#xff0c;今天先写个简单点的断言。 一般情况用响应断言&#xff0c;就挺好使&#xff0c;但是自动化还要生成报告&#xff0c;如果断言失败了&#xff0c;要保存结果&#xff0c;只能用beanshell处理&#xff0c;顺…

智慧矿山:EasyCVR助力矿井视频多业务融合及视频转发服务建设

一、方案背景 随着矿井安全生产要求的不断提高&#xff0c;视频监控、数据传输、通讯联络等业务的需求日益增长。为满足矿井生产管理的多元化需求&#xff0c;提高矿井作业的安全性和效率&#xff0c;TSINGSEE青犀EasyCVR视频汇聚/安防监控综合管理平台&#xff0c;旨在构建一…

【代码随想录】【算法训练营】【第55天】 [42]接雨水 [84]柱状图中最大的矩形

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 LeetCode。 day 55&#xff0c;又是一个周一&#xff0c;不能再坚持~ 题目详情 [42] 接雨水 题目描述 42 接雨水 解题思路 前提&#xff1a;雨水形成的情况是凹的, 需要前中后3个元素&#xff0c;计算该元…

java集合(1)

目录 一.集合概述 二. 集合体系概述 1. Collection接口 1.1 List接口 1.2 Set接口 2. Map接口 三. ArrayList 1.ArrayList常用方法 2.ArrayList遍历 2.1 for循环 2.2 增强for循环 2.3 迭代器遍历 一.集合概述 我们经常需要存储一些数据类型相同的元素,之前我们学过…

MySQL-核心知识要点

1、索引的数据结构-Btree BTree的优势&#xff1a; B树的内节点无data&#xff0c;一个节点可以存储更多的K-V对。在构造树时&#xff0c;需要的内节点会更少&#xff0c;那么树的层级也会越低。查询一条数据时&#xff0c;1. 扫描的层级低&#xff0c;扫描过的节点更少&…

端口被占用的解决办法、netstat命令;Linux ps命令详解,Linux查看进程

文章目录 一、端口被占用的原因二、端口被占用的解决方法2.1 Windows系统2.2 Linux系统 三、Linux命令补充3.1 Linux查看端口占用情况3.2 netstat命令详解3.3 ps命令3.3.1 常用命令3.3.2 拓展命令3.3.3 字段补充 运行软件或程序时&#xff0c;有时会出现以下问题、导致运行失败…

Matlab进阶绘图第62期—滑珠气泡图

在之前的文章中分享了滑珠散点图的绘制方法&#xff1a; 在此基础上&#xff0c;添加尺寸参数&#xff0c;通过散点的大小表示一个额外的特征&#xff0c;便是滑珠气泡图。 由于Matlab中没有现成的函数绘制滑珠气泡图&#xff0c;因此需要大家自行解决。 本文利用自己制作的B…

【重磅】万能模型-直接能换迪丽热巴的模型

万能模型&#xff0c;顾名思义&#xff0c;不用重新训练src&#xff0c;直接可以用的模型&#xff0c;适应大部分原视频脸 模型用法和正常模型一样&#xff0c;但可以跳过训练阶段&#xff01;直接到合成阶段使用该模型 本模型没有做Xseg&#xff0c;对遮挡过多的画面不会自动适…

centos7固定ip

1.查看虚拟网络配置 NAT设置&#xff1a; 2.修改网卡配置文件 [rootlocalhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33 TYPE"Ethernet" PROXY_METHOD"none" BROWSER_ONLY"no" BOOTPROTO"static" DEFROUTE"yes"…

springboot dynamic配置多数据源

pom.xml引入jar包 <dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.5.2</version> </dependency> application配置文件配置如下 需要主要必须配置…

【鸿蒙学习笔记】页面和自定义组件生命周期

官方文档&#xff1a;页面和自定义组件生命周期 目录标题 [Q&A] 都谁有生命周期&#xff1f; [Q&A] 什么是组件生命周期&#xff1f; [Q&A] 什么是组件&#xff1f;组件生命周期 [Q&A] 什么是页面生命周期&#xff1f; [Q&A] 什么是页面&#xff1f;页面生…

day04-numpy操作文件

操作文件 使用loadtxt读取文本、csv文件 loadtxt(fname, dtype<type float>, comments#, delimiterNone, convertersNone, skiprows0, usecolsNone, unpackFalse, ndmin0,encodingbytes)参数&#xff1a; fname&#xff1a;指定文件名称或字符串。支持压缩文件&#x…

zigbee笔记:六、看门狗定时器(Watch Dog)

一、看门狗基础 1、看门狗功能&#xff1a; 由于单片机的工作常常会受到来自外界电磁场的干扰&#xff0c;造成各种寄存器和内存的数据混乱&#xff0c;会导致程序指针错误等&#xff0c;程序运行可能会陷入死循环。程序的正常运行被打断&#xff0c;由单片机控制的系统无法继…

maven设置阿里云镜像源(加速)

一、settings.xml介绍 settings.xml是maven的全局配置文件&#xff0c;maven的配置文件存在三个地方 项目中的pom.xml&#xff0c;这个是pom.xml所在项目的局部配置文件用户配置&#xff1a;${user.home}/.m2/settings.xml全局配置&#xff1a;${M2_HOME}/conf/settings.xml 优…

QT实现GIF动图显示(小白版,可直接copy使用)

需要你自己提前设置好动图的位置&#xff0c;本例中存放于"/Users/PLA/PLA/PLA.gif widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMovie> #include <QLabel>class Widget : public QWidget {Q_OBJECTpublic:explicit Wid…

六西格玛项目实战:数据驱动,手机PCM率直线下降

在当前智能手机市场日益竞争激烈的背景下&#xff0c;消费者对手机质量的要求达到了前所未有的高度。PCM&#xff08;可能指生产过程中的某种不良率或缺陷率&#xff09;作为影响手机质量的关键因素&#xff0c;直接关联到消费者满意度和品牌形象。为了应对这一挑战&#xff0c…

系统工程与信息系统基础(下)

目录 政府信息化和电子政务 企业信息化和电子商务 基本的逻辑和流程 信息化的概念 信息化的目的和涉及得三类创新 信息化需求的三个层次 企业信息化的方法 信息系统战略规划——方法 BI&#xff08;商业智能&#xff09; 数据挖掘 数据湖 BPR&#xff08;业务流程重…

物联网工业级网关解决方案 工业4G路由器助力智慧生活

随着科技的飞速发展&#xff0c;无线通信技术正逐步改变我们的工作与生活。在这个智能互联的时代&#xff0c;一款高性能、稳定可靠的工业4G路由器成为了众多行业不可或缺的装备。工业4G路由器以其卓越的性能和多样化的功能&#xff0c;助力我们步入智慧新纪元。 一、快速转化&…

TikTok马来西亚直播网络怎么配置?

TikTok是一款全球流行的社交媒体应用&#xff0c;在东南亚地区拥有大量用户。在马来西亚这个多元化的国家&#xff0c;配置高效稳定的直播网络对TikTok的运营至关重要。 配置马来西亚直播网络的必要性 广泛的地理覆盖&#xff1a;马来西亚包括大片陆地和众多岛屿&#xff0c;网…