概要
下面这一大块代码主要练习了 运算符重载。设定了一个日期类。如有问题请看注释。
//Date.h
#include<iostream>
#include<Windows.h>
using namespace std;
class Day
{
private:
int _year;
int _month;
int _day;
public:
Day(int year = 2018, int month = 10, int day = 30);
bool _IsLeapyear(int year);
int _GetDaysOfMonth(int year, int month);
void Create_Day(int year, int month, int day);
friend ostream & operator << (ostream &_cout, const Day &d);
friend Day operator ++(Day &d, int);
friend Day & operator ++(Day &d);
friend Day operator +(Day d1, int days);
friend Day operator -(Day d1, int days);
friend bool operator == (const Day &d1,const Day &d2);
friend bool operator <(const Day &d1, const Day &d2);
friend bool operator >(const Day &d1,const Day &d2);
friend bool operator <=(const Day &d1,const Day &d2);
friend bool operator >=(const Day &d1,const Day &d2);
Day operator = (Day d1);
int Get_year();
int Get_month();
int Get_day();
};
class cal
{
private:
Day date;
char* Week[12];
int* year1[12];
int* year2[12];
public:
void Setinfo();
void Setyear(int** year);
void Inityear1(int **year);
void Inityear2(int **year);
void PrintCal();
void PrintCal_();
int FindDay();
int Zeller(int a, int b, int c);
};
//Date.cpp
#include"Date.h"
/***************************
这个函数是用来获得 _year的值
****************************/
int Day :: Get_year()
{
return _year;
}
/***************************
这个函数是用来获得 _month的值
****************************/
int Day::Get_month()
{
return _month;
}
/***************************
这个函数是用来获得 _day的值
****************************/
int Day::Get_day()
{
return _day;
}
/***************************
这个函数是用来设置一个日期的值
****************************/
void Day::Create_Day(int year, int month, int day)
{
_year = year;
_month = year;
_day = day;
}
/***************************
这个函数是构造函数,日期不正确
则会报错,并且将日期设置为默认值
1900 - 1 - 1
缺省定义为
2018 - 10 - 30
****************************/
Day:: Day(int year , int month, int day) :_year(year), _month(month), _day(day)
{
if (!(year > 0 && month >=1 && month <= 12 && (day <= _GetDaysOfMonth(year, month))))
{
printf("Day :: Day failed -> init default data 1900 - 1 -1 !\n");
_year = 1900;
_month = 1;
_day = 1;
}
}
/***************************
这个函数是用来检测year是不是闰年
****************************/
bool Day::_IsLeapyear(int year)
{
if (((year % 4 == 0) && (year % 100 != 0)) || year % 400 == 0)
{
return true;
}
return false;
}
/***************************
这个函数是用来获取某个月有多少天
****************************/
int Day :: _GetDaysOfMonth(int year, int month)
{
int Mon[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (2 == month && _IsLeapyear(year))
{
return Mon[month] + 1;
}
return Mon[month];
}
/***************************
这个函数是用来初始化一个 year[12]
数组的,将每个月按照月份分配好一个天数。
****************************/
void cal::Setyear(int **year)
{
//开辟空间
int gap_year = date.Get_year();
int i = 0;
int j = 0;
for (i = 0; i < 8; i = i + 2)
{
year[i] = (int *)malloc(sizeof(int)* 32);
}
year[7] = (int *)malloc(sizeof(int)* 32);
year[9] = (int *)malloc(sizeof(int)* 32);
year[11] = (int *)malloc(sizeof(int)* 32);
if ((((gap_year % 100) != 0) && ((gap_year) % 4 == 0)) || ((gap_year % 400) == 0))
{
year[1] = (int *)malloc(sizeof(int)* 30);
}
else
{
year[1] = (int *)malloc(sizeof(int)* 29);
}
year[3] = (int *)malloc(sizeof(int)* 31);
year[5] = (int *)malloc(sizeof(int)* 31);
year[8] = (int *)malloc(sizeof(int)* 31);
year[10] = (int *)malloc(sizeof(int)* 31);
//对内容初始化
}
/***************************
这个函数是用来初始化year1的,
将天数按照月份从小到大排序放入
****************************/
void cal::Inityear1(int ** year)
{
//开辟空间
int gap_year = date.Get_year();
int i = 0;
int j = 0;
//对内容初始化
for (i = 0; i < 12; i++)
{
if (i == 0 || i == 2 || i == 4 || i == 6 || i == 7 || i == 9 || i == 11)
{
for (j = 0; j < 32; j++)
{
if (j == 0)
{
year[i][0] = 31;
continue;
}
year[i][j] = j;
}
}
else if (i == 3 || i == 5 || i == 8 || i == 10)
{
for (j = 0; j < 31; j++)
{
if (j == 0)
{
year[i][0] = 30;
continue;
}
year[i][j] = j;
}
}
else if (i == 1)
{
if ((((gap_year % 100) != 0) && ((gap_year) % 4 == 0)) || ((gap_year % 400) == 0))
{
for (j = 0; j < 30; j++)
{
if (j == 0)
{
year[i][0] = 29;
continue;
}
year[i][j] = j;
}
}
else
{
for (j = 0; j < 29; j++)
{
if (j == 0)
{
year[i][0] = 28;
continue;
}
year[i][j] = j;
}
}
}
}
}
/***************************
这个函数是用来初始化year1的,
将天数按照整年从小到大排序放入
****************************/
void cal::Inityear2(int **year)
{
int i = 0;
int j = 0;
int count = 0;
int temp = 0;
for (i = 0; i < 12; i++)
{
temp = year[i][0];
for (j = 1; j < temp + 1; j++)
{
count++;
year2[i][j] = count;
}
}
}
/***************************
这个函数是用来初始化 year1,year2的
****************************/
void cal::Setinfo()
{
Setyear(year1);
Inityear1(year1);
Setyear(year2);
Inityear1(year2);
Inityear2(year2);
}
/***************************
这个函数是用来打印year1的
****************************/
void cal::PrintCal()
{
int i = 0;
int j = 0;
int temp = 0;
int count = 0;
int w = 0;
for (i = 0; i < 12; i++)
{
count = 0;
temp = year1[i][0];
w = cal::Zeller(date.Get_year(), i + 1, 1);
cout << " " << i + 1 << "月" << endl << endl;
cout << " 日 一 二 三 四 五 六" << endl;
for (j = 0; j < w; j++)
{
count++;
cout << " ";
}
for (j = 1; j < temp + 1; j++)
{
count++;
cout.width(5);
cout << year1[i][j];
if (count % 7 == 0)
{
cout << endl;
}
}
cout << endl << endl;
}
}
/***************************
这个函数是用来打印year2的
****************************/
void cal::PrintCal_()
{
int i = 0;
int j = 0;
int temp = 0;
int count = 0;
int w = 0;
for (i = 0; i < 12; i++)
{
count = 0;
temp = year2[i][0];
w = cal::Zeller(date.Get_year(), i + 1, 1);
cout<<" "<<i+1<<"月"<<endl<<endl;
cout << " 日 一 二 三 四 五 六" << endl;
for (j = 0; j < w; j++)
{
count++;
cout<<" ";
}
for (j = 1; j < temp + 1; j++)
{
count++;
cout.width(5);
cout << year2[i][j];
if (count % 7 == 0)
{
cout << endl;
}
}
cout << endl << endl;
}
}
/***************************
这个函数是用来计算每个月1号是
星期几的,为打印函数提供方法。
注:本来是使用Zeller公式,然后
发现Zeller不稳定,所以使用了年
基类,月基类,日基类算法。
****************************/
int cal:: Zeller(int a,int b, int c)
{
int e, f;
double x, y;
x = a;
y = x / 4;
e = (int)y;
if (y == e)
{
e = 2;//e是年基数
}
else
{
e = 1;
}
if (e = 1)
{
switch (b)
{
case 1:
b = 0;
break;
case 2:
b = 3;
break;
case 3:
b = 3;
break;
case 4:
b = 6;
break;
case 5:
b = 1;
break;
case 6:
b = 4;
break;
case 7:
b = 0;
break;
case 8:
b = 3;
break;
case 9:
b = 5;
break;
case 10:
b = 0;
break;
case 11:
b = 3;
break;
case 12:
b = 5;
break;
}
}
else
{
switch (b)
{
case 1:
b = 0;
break;
case 2:
b = 3;
break;
case 3:
b = 4;
break;
case 4:
b = 0;
break;
case 5:
b = 2;
break;
case 6:
b = 5;
break;
case 7:
b = 0;
break;
case 8:
b = 3;
break;
case 9:
b = 6;
break;
case 10:
b = 1;
break;
case 11:
b = 4;
break;
case 12:
b = 6;
break;
}//b是月基数
}
f = (a + a / 4 + a / 400 - a / 100 - e + b + c) % 7;
return f;
}
/***************************
这个函数是用来查找 date所处
的是一年当中的哪一天
****************************/
int cal::FindDay()
{
cout << date << " " << year2[date.Get_month() - 1][date.Get_day()];
return year2[date.Get_month() - 1][date.Get_day()];
}
/***************************
这个函数是用来重载后置++运算符
函数在内部使用了重载后的+号
提高了稳定性、安全性
****************************/
Day operator ++(Day &d, int)
{
Day temp = d;
d=d+1;
return temp;
}
/***************************
这个函数是用来重载前置++运算符
函数在内部使用了重载后的+号
提高了稳定性、安全性
****************************/
Day &operator ++(Day &d)
{
d = d+1;
return d;
}
/***************************
这个函数是用来重载+号,当加完天
后,这个date如果不稳定,那么就将
进行调整。这里的不稳定是指_day大于
_month容量
****************************/
Day operator +(Day d1, int days)
{
Day temp(d1);
if (days < 0)
{
return temp - (0 - days);
}
temp._day = temp._day + days;
while ((temp._day > temp._GetDaysOfMonth(temp._year, temp._month)))
{
temp._day = temp._day - temp._GetDaysOfMonth(temp._year, temp._month);
temp._month = temp._month + 1;
if (temp._month > 12)
{
temp._month = 1;
temp._year++;
}
}
return temp;
}
/***************************
这个函数是用来重载-号,当减完天
后,这个date如果不稳定,那么就将
进行调整。这里的不稳定是指_day小于
_month容量
****************************/
Day operator - (Day d1, int days)
{
Day temp(d1);
if (days < 0)
{
return temp + (0 - days);
}
Day day_t = temp._GetDaysOfMonth(temp._year, temp._month);
temp._day = temp._day - days;
while((temp._day < 0))
{
temp._day = temp._day + temp._GetDaysOfMonth(temp._year, temp._month);
day_t = temp._GetDaysOfMonth(temp._year, temp._month);
temp._month = temp._month - 1;
if (temp._month < 1)
{
temp._month = 12;
temp._year --;
}
}
return temp + 1;
}
/***************************
这个函数是用来重载输出运算符
将输出改为符合可读性原则的代码
****************************/
ostream & operator << (ostream &_cout, const Day &d)
{
_cout << d._year << "-" << d._month << "-" << d._day;
return _cout;
}
/***************************
这个函数是用来重载赋值运算符
赋值运算符的返回值是形参变量
实现了连续赋值。
****************************/
Day Day :: operator =(Day d1)
{
this->_year = d1._year;
this->_month = d1._month;
this->_day = d1._day;
return *this;
}
/***************************
这个函数是用来重载判断相等的
****************************/
bool operator == (const Day &d1,const Day &d2)
{
if ((d1._year == d2._year) && (d1._month == d2._month) && (d1._day == d2._day))
{
return true;
}
return false;
}
/***************************
这个函数是用来重载判断小于的
****************************/
bool operator <(const Day &d1,const Day &d2)
{
if ((d1._year > d2._year) || ((d1._year == d2._year) && (d1._month > d2._month)) || ((d1._year == d2._year) && (d1._month == d2._month) && (d1._day > d2._day)))
{
return true;
}
return false;
}
/***************************
这个函数是用来重载判断大于的
****************************/
bool operator >(const Day &d1,const Day &d2)
{
if ((d1._year < d2._year) || ((d1._year == d2._year) && (d1._month < d2._month)) || ((d1._year == d2._year) && (d1._month == d2._month) && (d1._day < d2._day)))
{
return true;
}
return false;
}
/***************************
这个函数是用来重载判断小于等于的
****************************/
bool operator <=(const Day &d1,const Day &d2)
{
if (d1 < d2 || d1 == d2)
{
return true;
}
return false;
}
/***************************
这个函数是用来重载判断大于等于的
****************************/
bool operator >=(const Day &d1,const Day &d2)
{
if (d1 > d2 || d1 == d2)
{
return true;
}
return false;
}