本篇部落客要是實作一個日期類,這就要求你必須對構造函數,拷貝構造函數,指派運算符重載,輸出運算符重載,友元函數等等都要熟悉
#include<iostream>
using namespace std;
class Date
{
public:
Date(int year = 2000, int month = 1, int day = 1);
Date(const Date&d);
int IsLeapYear();
Date& operator++();
Date operator++(int);
Date& operator--();
Date operator--(int);
Date operator-(int day);
Date operator+ (int day);
int operator-(const Date&d);
int operator==(const Date&d);
int operator!=(const Date&d);
int operator>(const Date&d);
int operator<(const Date&d);
friend ostream& operator<<(ostream&cout, const Date d);
Date& operator= (const Date&d);
private:
int GetMonthDays(int month)//擷取每個月的天數
{
int days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (IsLeapYear() && (2 == month))
{
days[month] += 1;
}
return days[month];
}
int _year;
int _month;
int _day;
};
Date::Date(int year, int month, int day)//構造函數,初始值在聲明中給出(聲明和定義中一處給出即可)
:_year(year)
, _month(month)
, _day(day)
{
//判斷輸入的日期是否合法
if (!((year > 0) && (month > 0 && month<13) && (day>0 && day <= GetMonthDays(month))))
{
_year = 1900;
_month = 1;
_day = 1;
}
}
Date::Date(const Date&d)//拷貝構造
:_year(d._year)
, _month(d._month)
, _day(d._day)
{}
int Date::IsLeapYear()//判斷是否是閏年
{
if (((_year % 4 == 0) && (_year % 100 != 0)) || (_year % 400 == 0))
{
return 1;
}
return 0;
}
Date& Date:: operator++()//前置++
{
*this=*this+1;
return *this;//*this比函數生命周期長,是以可以引用傳回,效率高
}
Date Date:: operator++(int)//後置++
{
Date tmp = *this;
*this=*this + 1;
return tmp;//因為tmp周期比函數生命周期短是以值傳回
}
Date& Date:: operator--()//前置--
{
*this=*this - 1;
return *this;
}
Date Date:: operator--(int)//後置--
{
Date tmp = *this;
*this = *this - 1;
return tmp;
}
Date Date:: operator-(int day)//一個日期減去一個天數
{
if (day < 0)
{
return *this + (0 - day);
}
Date tmp = *this;
tmp._day -= day;
while (tmp._day <= 0)
{
tmp._month-=1;
if (tmp._month <= 0)
{
tmp._year-=1;
tmp._month = 12;
}
//GMD函數指擷取tmp._month這個月的天數
tmp._day += tmp.GetMonthDays(tmp._month);
}
return tmp;
}
Date Date:: operator+ (int day)//一個日期加上一個天數
{
if (day<0)
{
return *this - (0 - day);
}
Date tmp = *this;
tmp._day += day;
int daysInMonth = tmp.GetMonthDays(tmp._month);
while (tmp._day > daysInMonth)
{
tmp._day -= daysInMonth;
tmp._month++;
if (tmp._month > 12)
{
tmp._year++;
tmp._month=tmp._month-12;
}
}
return tmp;
}
int Date:: operator-(const Date&d)//測試兩個日期之間間隔的天數
{
Date maxdate(*this);
Date mindate(d);
if (maxdate < mindate)
{
maxdate = mindate;
mindate = *this;
}
int count = 0;
while (mindate < maxdate)
{
mindate = mindate + 1;
++count;
}
return count;
}
int Date:: operator==(const Date&d)//判斷兩個日期相等
{
if ((_year == d._year) && (_month == d._month) && (_day == d._day))
return 1;
return 0;
}
int Date:: operator!=(const Date&d)//判斷不等
{
if ((_year != d._year) || (_month != d._month) || (_day != d._day))
return 1;
return 0;
}
//傳回值類型當然也可以給bool類型
int Date:: operator>(const Date&d)//判斷大于
{
if (((_year == d._year) || (_year > d._year)) && ((_month == d._month) || (_month > d._month)) && ((_day > d._day) || (_day == d._day)))
return 1; //代表判斷成立
return 0;//判斷不成立
}
int Date:: operator<(const Date&d)//判斷小于
{
if ((_year <d._year) || (_month < d._month) || (_day < d._day))
return 1;
return 0;
}
//輸出運算符重載,因為友元函數不屬于類成員是以不用加作用域限定符Date::
ostream& operator<<(ostream&cout, const Date d)
{
cout << d._year << "-" << d._month << "-" << d._day;
return cout;
}
Date& Date:: operator= (const Date&d)//指派運算符重載
{
if (this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
void FunTest()
{
Date d1(2017, 1, 1);
Date d2(2017, 12, 31);//測試構造函數
Date d3= d2;//測試拷貝構造,加指派運算符重載
Date d4(2017, 1, 1);
cout << --d1 << endl;//測試前置--
cout << d1--<< endl;//測試後置--
cout << ++d2 << endl;//測試前置++
cout << d2++<< endl;//測試後置++
cout<<(d1 > d2)<<endl;//測試>
cout << (d4+1) << endl;//測試一個日期加上幾天
cout << d1 - d2 << endl;//測試兩個日期之間的天數
}
int main()
{
FunTest();
system("pause\n");
return 0;
}
其他的讀者可自行測試。