天天看點

日期類的實作(其中包括構造函數,拷貝構造,指派運算符重載,輸出運算符重載,友元函數等等)

本篇部落客要是實作一個日期類,這就要求你必須對構造函數,拷貝構造函數,指派運算符重載,輸出運算符重載,友元函數等等都要熟悉

#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;
}
           
日期類的實作(其中包括構造函數,拷貝構造,指派運算符重載,輸出運算符重載,友元函數等等)

其他的讀者可自行測試。

繼續閱讀