一、 实验目的
1. 理解运算符重载概念;
2. 学会使用运算符重载;
3. 练习类和对象的使用。
二、实验内容
设计一个日期类Date,包括年、月、日等私有数据成员。要求实现日期的基本运算,如某日期加上天数、某日期减去天数、两日期相差的天数等。
三、实验要求
在Date类中设计如下重载运算符函数:
Date operator+(int days):返回某日期加上天数得到的日期
Date operator-(int days):返回某日期减去天数得到的日期
int operator-(Date&b):返回两日期相差的天数
在实现这些重载运算符函数时调用以下私有成员函数:
leap(int):判断指定的年份是否为闰年
dton(Date &):将指定日期转换成从0年O月O日起的天数
ntod(int):将指定的0年O月O日起的天数转换成对应的日期
提示:可定义一个二维数组,存放闰年和非闰年每个月的天数,用于后面的计算,
int day_tab[2][12]={{31,28,31,30,3l,30,3l,3l,30,31,30,31},
{31,29,31,30,31,30,31,31,30,31,30,31}};
// day_tab二维数组存放各月天数,第一行对应非闰年,第二行对应闰年
附代码
!!!编译环境 DevC++ 5.11 TDM-GCC 4.9.2 64-Bit Release
头文件 iquery.h
#ifndef _IQUERY_H
#define _IQUERY_H 1
using namespace std;
//要求实现日期的基本运算,如某日期加上天数、某日期减去天数、两日期相差的天数等
class Date{
private:
int year;
int month;
int day;
bool leap(int idx); //判断指定的年份是否为闰年
int dton(Date &pdate); //将指定日期转换成从0年O月O日起的天数
Date ntod(int n); //将指定的0年O月O日起的天数转换成对应的日期
//day_tab二维数组存放各月天数,第一行对应非闰年,第二行对应闰年
public:
Date(int y=0,int m=0,int d=0):year(y),month(m),day(d){};
Date operator+(int days); //返回某日期加上去天数得到的日期
Date operator-(int days); //返回某日期减去天数得到的日期
int operator-(Date&b); //返回两日期相差的天数
void Show();
friend ostream &operator<<(ostream &os,Date &s);//重载流运算符<<
friend istream &operator>>(istream &is,Date &s);//重载流运算符>>
};
#endif
头文件实现文件 iquery,cpp
#include <iostream>
#include "string"
#include "iquery.h"
#include "iomanip"
using namespace std;
int day_tab[2][12]={{31,28,31,30,3l,30,3l,3l,30,31,30,31}, {31,29,31,30,31,30,31,31,30,31,30,31}};
//判断指定的年份是否为闰年
bool Date::leap(int idx){
if(idx%400==0||(idx%4==0&&idx%100!=0))
return true;
else return false;
}
//将指定日期转换成从0年O月O日起的天数
int Date::dton(Date &pdate){
int y,m,days =0;
for(y=1;y<=pdate.year;y++){
if(leap(y))
days+=366; //闰年时加366天
else
days+=365; //非闰年时加365天
}
if(leap(pdate.year)){
for(m=0;m<pdate.month-1;m++){
days+=day_tab[1][m];
}
}
else{
for(m =0;m<pdate.month-1;m++){
days+=day_tab[0][m];
}
}
days+=pdate.day;
return days;
}
//将指定的0年O月O日起的天数转换成对应的日期
Date Date::ntod(int n){
int y=1,m=1,d,rest=n,lp;
while(1){
if(leap(y)){
if(rest<= 366) break;
else
rest-=366;
}
else{
if(rest <= 365 ) break; //非闰年
else
rest-=365;
}
y++;
}
y--;
lp=leap(y);
while(1){
if(lp){
if(rest>day_tab[1][m-1])
rest-=day_tab[1][m-1];
else break;
}
else{
if(rest>day_tab[0][m-1])
rest-=day_tab[0][m-1];//非闰
else break;
}
m++;
}
d=rest;
return Date(y,m,d);
}
//返回某日期加上去天数得到的日期
//Date *_date=new Date;delete _date;
Date Date::operator+(int days){
static Date _date;
int number=dton(*this)+days;
_date=ntod(number);
return _date;
}
//返回某日期减去天数得到的日期
Date Date::operator-(int days){
static Date _date;
int number=dton(*this)-days;
_date=ntod(number);
return _date;
}
//返回两日期相差的天数
int Date::operator-(Date&b){
int days;
days=dton(*this)-dton(b); //为什么要减1
return days;
}
void Date::Show(){
cout<<year<<"-"<<month<<"-"<<day<<endl;
}
ostream& operator<<(ostream &os,Date &s){
os<<s.year<<"-";
os<<s.month<<"-";
os<<s.day<<"\t"<<endl;
return os;
}
istream &operator>>(istream &is,Date &s){
cout<<" 请按顺序输入年 月 日"<<endl;
is>>s.year;
is>>s.month;
is>>s.day;
cout<<endl;
return is;
源码 main.cpp
#include <iostream>
#include "string"
#include "iquery.h"
#include "iomanip"
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
int main(int argc, char** argv) {
Date now(2018,04,26),then,t3,t4;
cout<<"请输入现在时间:"<<endl;
cin>>now;
cout<<"请输入下一个时间:"<<endl;
cin>>then;
cout<<"now is "<<now<<"then is "<<then;
cout<<"相差天数:"<<(then-now)<<endl;
t3=now+2;t4=now-2;
cout<<"now + 2:"<<t3;t3.Show();
cout<<"now - 2:"<<t4;t4.Show();
cout<<endl<<now;
return 0;
}
注:
已经出现过的error:
- [Warning] non-static data member initializers only available with -std=c++11 or -std=gnu++11
- 非静态成员函数在.h文件里的初始化列表仅适用于-std=c++11 or -std=gnu++11
- [Warning] extended initializer lists only available with -std=c++11 or -std=gnu++11
- 扩展的初始化列表仅适用于-std=c++11 or -std=gnu++11
存在的问题:
可行性优化:
- 装GCC 4.8以上版本,默认支持最新的标准,如果没有生效,添加编译参数 -std=c++11