一、 實驗目的
- 理解運算符重載概念;
- 學會使用運算符重載;
- 練習類和對象的使用。
二、實驗內容
設計一個日期類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