目录
1.获取某年某月的天数
首先要实现一个获取月份天数的函数,要实现是否是闰年或平年,以及二月份的天数
int GetMonthDay(int year, int month);
获取某年某月的天数
GetMonthDay(int year, int month)
{
//为了与下标相符合,定义成静态就不用一直创建
static int arr[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };//平年
if (year % 4 == 0 && year %100 != 0 || year % 400 == 0)//闰年
{
arr[2] = 29;
}
return arr[month];
}
2.全缺省的构造函数
Date(int year = 1900, int month = 1, int day = 1);
Date(int year = 1900, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
3. 拷贝构造函数
知识点:拷贝构造,内置类型,自定义类型都会处理。默认赋值重载跟拷贝构造一个性质,拷贝构造是定义时,赋值重载是两个已经存在的。
Date(const Date& d) // d2(d1)
Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
4.赋值运算符重载
知识点:赋值运算符只能重载成类的成员函数不能重载成全局函数
Date& operator=(const Date& d)
Date& operator=(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
return *this;
}
5.析构函数
知识点:析构函数不能重载,只能删除一次
~Date()
~Date()
{
_year = 0;
_month = 0;
_day = 0;
}
6.日期+=天数
知识点:日期+=天数,+=改变了自身,*this空间没有销毁,所以可以加引用返回
Date& operator+=(int day)
Date& operator+=(int day)
{
//举例子:4月,_day为10,day是60
_day = day + _day;
while (_day > GetMonthDay(_year, _month))
{
int i = GetMonthDay(_year, _month);//某年某月的天数
_day = _day - i;
++_month;
if (_month == 13)
{
_month = 1;
}
}
return *this;
}
7.日期+天数
Date operator+(int day)
知识点:+和+=一个自身的值变了一个没变,Date tmp = *this;//等价于Date tmp(*this)拷贝构造,因为两个已经存在的对象才是赋值
Date operator+(int day)
{
Date tmp = *this;//等价于Date tmp(*this)拷贝构造,因为两个已经存在的对象才是赋值
tmp._day = day + tmp._day;
while (tmp._day > GetMonthDay(tmp._year, tmp._month))
{
int i = GetMonthDay(tmp._year, tmp._month);//某年某月的天数
tmp._day = _day - i;
tmp._month++;
if (tmp._month == 13)
{
tmp._month = 1;
}
}
return tmp;
}
8.日期-天数
Date operator-(int day)
Date operator-(int day)
{
Date tmp = *this;//等价于Date tmp(*this)拷贝构造,因为两个已经存在的对象才是赋值
//举例子:4月,_day为10,day是60
tmp._day = tmp._day-day;
while (tmp._day < 0)
{
int i = GetMonthDay(tmp._year, tmp._month-1);//某年某月的天数
if (tmp._month - 1 == 0)
{
tmp._month = 12;
}
tmp._day = tmp._day + i;
tmp._month--;
if (tmp._month == 0)
{
tmp._month = 12;
}
}
return tmp;
}
9.日期-=天数
Date& operator-=(int day)
// 日期-=天数
Date& operator-=(int day)
{
//举例子:4月,_day为10,day是60
_day = _day - day;
while (_day < 0)
{
int i = GetMonthDay(_year, _month - 1);//某年某月的天数
if (_month - 1 == 0)
{
_month = 12;
}
_day = _day + i;
_month--;
if (_month == 0)
{
_month = 12;
}
}
return *this;
}
10.前置++
Date& operator++()
// 前置++
Date& operator++()
{
*this += 1;
return *this;
}
11.// 后置++
知识点:// 后置++,后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存一份,然后给this + 1
// 后置++,后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存一份,然后给this + 1
Date operator++(int)
{
Date temp(*this);
*this += 1;
return temp;
}
区别:一个不改变自己的值,一个改变,后置括号里有int,前置没有
12.后置--
// 后置--
Date operator--(int)
{
Date temp(*this);
_day -= 1;
return temp;
}
13.前置--
// 前置--
Date& operator--()
{
_day -= 1;
return *this;
}
14.>运算符重载
内置类型可以直接比较,而自定义类型不能直接比较,要用运算符重载
技巧:先写一个大于一个等于,其他的直接!就好了
bool operator>(const Date& d) const
{
if (_day > d._day && _month >= d._month && _year >= d._year)
{
return true;
}
else if (_day < d._day && _month >= d._month && _year >= d._year)
{
return true;
}
else if (_day < d._day && _month <= d._month && _year > d._year)
{
return true;
}
else
{
return false;
}
}
15.==运算符重载
bool operator==(const Date& d)
{
return _year == d._year && _month == d._month && _day == d._day;
}
16.>=运算符重载
bool operator >= (const Date& d)
{
return *this > d || *this == d;
}
17.<=运算符重载
bool operator <= (const Date& d)
{
return !(*this > d);
}
18.<运算符重载
bool operator < (const Date& d)
{
return !(*this >= d);
}
19.!=运算符重载
bool operator != (const Date& d)
{
return !(*this == d);
}
20.日期 - 日期 返回天数
int operator-(const Date& d)
{
Date max = *this;
Date min = d;
int n = 0;//定义相差天数
int flag = 1;
if (*this < d)
{
max = d;
min = *this;
flag = -1;
}
while (min != max)
{
min++;
++n;
}
return flag * n;
}
21.流插入
知识点:流插入流提取只能写在类外,因为需要两个接收值,要是在类内就会有隐藏的this指针,要用friend,友元函数声明
ostream& operator<<(ostream& out, const Date& d);//ostream前不能加const,d不可被修改必须加
ostream& operator<<(ostream& out, const Date& d)//ostream前不能加const,d不可被修改必须加
{
out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
return out;
}
22.流提取
istream& operator>>(istream& in, Date& d)//不支持写const
istream& operator>>(istream& in, Date& d)//不支持写const
{
in >> d._year >> d._month >> d._day;
return in;
}
23.总代码
#include<iostream>
using namespace std;
class Date
{
//单个友元函数声明,为了访问private中的数据,不写访问不到
//friend void operator<<(ostream& out, const Date& d);
//多个友元函数声明,为了访问private中的数据,不写访问不到
friend ostream& operator<<(ostream& out, const Date& d);
//流提取
friend istream& operator>>(istream& out, Date& d);//
public:
// 获取某年某月的天数
int GetMonthDay(int year, int month)
{
//为了与下标相符合,定义成静态就不用一直创建
static int arr[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };//平年
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)//闰年
{
arr[2] = 29;
}
return arr[month];
}
// 全缺省的构造函数
Date(int year = 1900, int month = 1, int day = 1)
{
_year = year;
_month = month;
_day = day;
}
// 拷贝构造函数
// d2(d1)
Date(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
// 赋值运算符重载,赋值运算符只能重载成类的成员函数不能重载成全局函数
Date& operator=(const Date& d)
{
_year = d._year;
_month = d._month;
_day = d._day;
return *this;
}
// 析构函数
~Date()
{
_year = 0;
_month = 0;
_day = 0;
}
// 日期+=天数,+=改变了自身,*this空间没有销毁,所以可以加引用返回
Date& operator+=(int day)
{
//举例子:4月,_day为10,day是60
_day = day + _day;
while (_day > GetMonthDay(_year, _month))
{
int i = GetMonthDay(_year, _month);//某年某月的天数
_day = _day - i;
++_month;
if (_month == 13)
{
_month = 1;
}
}
return *this;
}
// 日期+天数
Date operator+(int day)
{
Date tmp = *this;//等价于Date tmp(*this)拷贝构造,因为两个已经存在的对象才是赋值
tmp._day = day + tmp._day;
while (tmp._day > GetMonthDay(tmp._year, tmp._month))
{
int i = GetMonthDay(tmp._year, tmp._month);//某年某月的天数
tmp._day = _day - i;
tmp._month++;
if (tmp._month == 13)
{
tmp._month = 1;
}
}
return tmp;
}
// 日期-天数
Date operator-(int day)
{
Date tmp = *this;//等价于Date tmp(*this)拷贝构造,因为两个已经存在的对象才是赋值
//举例子:4月,_day为10,day是60
tmp._day = tmp._day-day;
while (tmp._day < 0)
{
int i = GetMonthDay(tmp._year, tmp._month-1);//某年某月的天数
if (tmp._month - 1 == 0)
{
tmp._month = 12;
}
tmp._day = tmp._day + i;
tmp._month--;
if (tmp._month == 0)
{
tmp._month = 12;
}
}
return tmp;
}
// 日期-=天数
Date& operator-=(int day)
{
//举例子:4月,_day为10,day是60
_day = _day - day;
while (_day < 0)
{
int i = GetMonthDay(_year, _month - 1);//某年某月的天数
if (_month - 1 == 0)
{
_month = 12;
}
_day = _day + i;
_month--;
if (_month == 0)
{
_month = 12;
}
}
return *this;
}
// 前置++
Date& operator++()
{
*this += 1;
return *this;
}
// 后置++,后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将this保存一份,然后给this + 1
Date operator++(int)
{
Date temp(*this);
*this += 1;
return temp;
}
// 后置--
Date operator--(int)
{
Date temp(*this);
_day -= 1;
return temp;
}
// 前置--
Date& operator--()
{
_day -= 1;
return *this;
}
// >运算符重载
bool operator>(const Date& d) const
{
if (_day > d._day && _month >= d._month && _year >= d._year)
{
return true;
}
else if (_day < d._day && _month >= d._month && _year >= d._year)
{
return true;
}
else if (_day < d._day && _month <= d._month && _year > d._year)
{
return true;
}
else
{
return false;
}
}
// ==运算符重载
bool operator==(const Date& d)
{
return _year == d._year && _month == d._month && _day == d._day;
}
// >=运算符重载
bool operator >= (const Date& d)
{
return *this > d || *this == d;
}
// <=运算符重载
bool operator <= (const Date& d)
{
return !(*this > d);
}
// <运算符重载
bool operator < (const Date& d)
{
return !(*this >= d);
}
// !=运算符重载
bool operator != (const Date& d)
{
return !(*this == d);
}
// 日期-日期 返回天数
//int operator-(const Date& d)
//{
// //举例子:1990年4月20,和1993年5月28,假设*this小
// if (*this < d)
// {
// //this的总天数(不带年的)
// int sum = 0; int t = _month-1;
// while (t--)
// {
// int i = GetMonthDay(_year, t);//*this的
// sum = sum + i;
// }
// sum = sum + _day;
// //d的
// int sum1 = 0; int t1 = d._month-1;
// while (t1--)
// {
// int i = GetMonthDay(d._year, t1);//d的
// sum1 = sum1 + i;
// }
// sum1 = sum1 + d._day;
// return sum1 - sum;
// //int rs = 0;
// //if (d._year - _year==1)
// //{
// // if (_year % 4 == 0 && _year % 100 != 0 || _year % 400 == 0)//闰年
// // {
// // int rs = 366;//this是闰年,则天数为366天
// // }
// //}
// //else
// //{
// //}
// //int k = rs - sum;//this减去this日期剩的天数
// //return k + sum1;
// }
//}
//日期 - 日期 返回天数
//2003 10月10日 举例子
//2002 9月10日
int operator-(const Date& d)
{
Date max = *this;
Date min = d;
int n = 0;//定义相差天数
int flag = 1;
if (*this < d)
{
max = d;
min = *this;
flag = -1;
}
while (min != max)
{
min++;
++n;
}
return flag * n;
}
void print()const
{
cout << _year << " " << _month << " " << _day << endl;
}
private:
int _year;
int _month;
int _day;
};
//单个流插入声明
//void operator<<(ostream& out, const Date& d);
//
//
//多个流插入声明
ostream& operator<<(ostream& out, const Date& d);//ostream前不能加const,d不可被修改必须加
//流提取
istream& operator>>(istream& out, Date& d);//
//多个流插入
ostream& operator<<(ostream& out, const Date& d)//ostream前不能加const,d不可被修改必须加
{
out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
return out;
}
//流提取
istream& operator>>(istream& in, Date& d)//不支持写const
{
in >> d._year >> d._month >> d._day;
return in;
}
test(重要知识点)
Date d3(1900, 2, 1);
连续的流插入,需要有返回值,跟内置类型差不多
cout << d2 << d1 << d3;//d2先流入
int main()
{
/*Date d1(1900, 7, 20);
Date d2(1900, 5, 29);*/
/*d1 + 40;
d1.print();*///结果还是d1,因为是加没有改变d1本身
//d1 += 40;
//d1.print();//这个才是
//d1 -= 60;
//d1.print();
//int i=(d1 == d2) ;
///*printf("%d", i);*/
//cout << (d1 == d2) << endl;
//cout << (d2 > d1) << endl;
//cout << (d2 <= d1) << endl;
//cout << (d1 - d2)<<endl;
//cout << d1;//两个等价
//operator<<(cout, d1);
//Date d3(1900, 2, 1);
连续的流插入,需要有返回值,跟内置类型差不多
//cout << d2 << d1 << d3;//d2先流入
流提取
//cin >> d2 >> d1;
//cout<< d2 << d1;
const Date d6(1900, 9, 9);
d6.print();//不能这样调用,要在print处加上const,但是不带const的照样打印,可以缩小权限,但不能放大
Date d7(1900, 9, 9);
d7.print();
d7 > d6;//可以担d6>d7不可以,operator接受的时候,const在右边,在左边也加上const,d6>d7才能实现
d6 > d7;//不改变值的都可以加上const
return 0;
}