1. 程式人生 > >c++實現日期類(class Date) 建構函式 拷貝構造 操作符過載(輸入輸出 比較操作 算數運算 自增自減)

c++實現日期類(class Date) 建構函式 拷貝構造 操作符過載(輸入輸出 比較操作 算數運算 自增自減)

註釋比較詳細,可以直接跑起來,直接上程式碼(vs2012 win7)

一、標頭檔案

/**************
	Date.h
***************/

#pragma once
#include <iostream>
using namespace std;

class Date
{
private:
	int my_iYear;
	int my_iMonth;
	int my_iDay;
	int GetOneMonthDays(int year, int month)const;//獲取某個月的天數

public:
	Date()
		:my_iYear(1900)
		,my_iMonth(1)
		,my_iDay(1)
	{
	}
	Date(int year, int month, int day);// 建構函式
	Date(const Date& d);		       // 拷貝建構函式
	~Date(){}					       // 解構函式
	
	int GetYear()const;		// 返回年份
	int GetMonth()const;	// 返回月份
	int GetDay()const;		// 返回天數

	void Print()const;			        // 輸出日期
	bool IsLeapYear()const;				// 判斷當前物件年是否是閏年
	bool IsLeapYear(const int y)const;  // 判斷指定年份是否是閏年

	// 操作符過載部分

	// 天數 + 日期
	friend Date operator+(const  int d, const Date date);

	// 日期 +  天數
	friend Date operator + (const Date date, const   int d);

	// 前置 ++ 
	friend Date& operator ++ (Date& date);

	// 後置 ++   多一個int引數與前置區別
	friend Date operator ++ (Date& date, int);

	// 過載 +=
	friend Date operator +=(Date& date, const int d);

	// 日期 - 天數
	friend Date operator - (const Date date, const int d);

	// 天數 - 日期
	friend Date operator - (const int d, const Date date);

	// 前置 --
	friend Date& operator -- (Date& date);

	// 後置 -- 
	friend Date operator -- (Date& date, int);
	
	// 過載 -=
	friend Date operator -=(Date& date, const int d);

	// 日期 - 日期
	friend int operator - (const Date a, const Date b);

	// 過載比較操作符
	friend bool operator< (const Date a, const Date b);

	friend bool operator<= (const Date a, const Date b);

	friend bool operator> (const Date a, const Date b);

	friend bool operator>= (const Date a, const Date b);

	friend bool operator== (const Date a, const Date b);

	friend bool operator!= (const Date a, const Date b);

	// 過載輸出運算子 <<
	friend ostream& operator <<(ostream& _out, const Date& date);

	// 過載輸入運算子 >>
	friend istream& operator >> (istream& _out,  Date& date);

};


二、實現詳情Date.cpp

#include "Date.h"

//建構函式
Date::Date(int year = 1900,int month = 1, int day = 1)
	:my_iYear(year)
	,my_iMonth(month)
	,my_iDay(day)
{
	//檢測年份月份天數的合法性 
	if (  year<= 0  ||
	      (month<=0 || month>12) ||
	      (day <= 0 || day>GetOneMonthDays(year, month)) ) 
	{
		my_iYear = 1900;
		my_iMonth = 1;
		my_iDay = 1;
	}
}

//拷貝建構函式
Date::Date(const Date& d)
{
	my_iYear = d.my_iYear;
	my_iMonth = d.my_iMonth;
	my_iDay = d.my_iDay;
}

//獲取某月中的天數
int Date::GetOneMonthDays(int year, int month)const
{
	// a[1] - a[12] 表示非閏年每月天數
	int a[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};

	// 二月份天數做特殊處理 平年28 閏年29天
	if (month == 2)
	{
		a[2] += IsLeapYear(year);
	}
	return a[month];
}

// 返回年份
int Date::GetYear()const
{
	return my_iYear;
}

// 返回月份
int  Date::GetMonth()const
{
	return my_iMonth;
}

// 返回天數
int  Date::GetDay()const
{
	return my_iDay;
}

// 輸出日期
void  Date::Print()const
{
	cout << my_iYear << " 年 " << my_iMonth << " 月 " << my_iDay << " 日 " <<endl;
}

// 判斷當前年是否是閏年
bool  Date::IsLeapYear()const
{
	if (my_iYear%400 == 0 || (my_iYear%4==0 && my_iYear%100!=0))
	{
		return true;
	}
	return false;
}		

// 判斷指定年份是否是閏年
bool  Date::IsLeapYear(const int year)const
{
	if (year%400 == 0 || (year%4==0 && year%100!=0))
	{
		return true;
	}
	return false;
}

// 操作符過載部分

// 天數 + 日期
Date operator+(const  int d, const Date date)
{
	Date tmpDate = date;
	if (0 == d)  return date;   // 加的天數為0 返回本身的值

	// 獲取當前物件對應月份的天數
	int days; 
	if (d > 0)
	{
		tmpDate.my_iDay += d;       
		while (tmpDate.my_iDay > (days = tmpDate.GetOneMonthDays(tmpDate.my_iYear, tmpDate.my_iMonth)))   //加天數後對不合理值處理
		{
			//2010.3.12  + 30   2012.3.42 > 31  2012.4.42 - 31
			//減去該月的天數
			tmpDate.my_iDay -= days;
			tmpDate.my_iMonth ++;		 //  月份增加一個月

			if (tmpDate.my_iMonth > 12)	 //處理月份不合理
			{
				tmpDate.my_iYear ++;	 
				tmpDate.my_iMonth = 1;   //超過12後年份++ 月份置1
			}
		}
	}
	else
	{
		return date - (0 - d);
	}

	return tmpDate;
}

// 日期 +  天數
Date operator + (const Date date, const  int d)
{
	return d + date;
}

// 前置 ++ 
Date& operator ++ (Date& date)
{
	date = date  + 1;
	return date;
}


// 後置 ++   多一個int引數與前置區別
Date operator ++ (Date& date, int)
{
	Date temp = date;
	date =  date + 1;
	return temp;
}

// 過載 +=
Date operator +=(Date& date, const int d)
{
	date = date + d;
	return date;
}

// 日期 - 天數
Date operator - (const Date date, const int d)
{
	Date tempDate = date;
	if (0 == d) return date;

	if ( d>0 )
	{
		tempDate.my_iDay -= d;
		while (tempDate.my_iDay <= 0)
		{
			--tempDate.my_iMonth;
			if (tempDate.my_iMonth == 0)
			{
				--tempDate.my_iYear;
				tempDate.my_iMonth = 12;
			}
			tempDate.my_iDay += tempDate.GetOneMonthDays(tempDate.my_iYear, tempDate.my_iMonth);
		}
	}
	else
	{
		return date + ( - d);
	}
	return tempDate;
}

// 天數 - 日期
Date operator - (const int d, const Date date)
{
	return date - d;
}

// 前置 --
Date& operator -- (Date& date)
{
	date = date - 1;
	return date;
}

// 後置 --
Date operator -- (Date& date, int)
{
	Date temp = date;
	date = date - 1;
	return temp;
}

// 過載 -=
Date operator -=(Date& date, const int d)
{
	date = date - d;
	return date;
}

// 日期 - 日期
int	operator - (const Date a, const Date b)
{
	int sumDay = 0;
	if (a==b)
	{
		return 0;
	}
	else if(a>b)
	{
		Date temp = b;
		while (temp!=a)
		{
			temp++;
			sumDay++;
		}
	}
	else // a<b
	{
		Date temp = a;
		while (temp!=b)
		{
			temp++;
			sumDay++;
		}
	}
	return sumDay;
	// 2016.1.1 - 2015.12.20
}


//過載比較操作符部分
// 判相等
bool operator== (const Date a, const Date b)
{
	// 同年同月同日
	return (a.my_iYear == b.my_iYear && a.my_iMonth == b.my_iMonth && a.my_iDay == b.my_iDay);
}

// 判不等
bool operator!= (const Date a, const Date b)
{
	// 對判相等取反即可 a和b相等時 取反 不相等判斷為假
	return !(a==b);
}

// 判小於
bool operator< (const Date a, const Date b)
{
	//先處理不小於 2016 10 29 2016 10 29   同年看月 同年同月看日
	if (a.my_iYear > b.my_iYear||
		(a.my_iYear == b.my_iYear && a.my_iMonth > b.my_iMonth)||
		(a.my_iYear == b.my_iYear && a.my_iMonth == b.my_iMonth && a.my_iDay >= b.my_iDay)
		)
	{
		return false;
	}
	return true;
}

// 判小於等於
bool operator<= (const Date a, const Date b)
{
	if (a<b ||a==b)
	{
		return true;
	}
	return false;
}

// 判大於
bool operator> (const Date a, const Date b)
{
	return !(a<=b);
}

// 判大於等於
bool operator>= (const Date a, const Date b)
{
	if (a>b || a==b)
	{
		return true;
	}
	return false;
}

// 過載輸出運算子 <<
std::ostream& operator<<(ostream& _out, const Date& date)
{
	_out << date.GetYear() << " 年 " << date.GetMonth() << " 月 " << date.GetDay() << " 日 " <<endl;
	return _out;
}

// 過載輸入運算子 <<
std::istream& operator >> (istream& _in, Date& date)
{
	int year = 0,month = 0,day = 0;
	cin >> year >> month >> day;
	Date temp(year,month,day);
	date = temp;
	return _in;
}




三、主函式,做了一些基本測試(臉滾鍵盤)Test.cpp

#include "Date.h"

int main()
{
	Date d1;
	d1.Print();
	cout << "----------------------1------------------"<< endl;

	Date d2(2016, 10 , 1);
	d2.Print();
	++d2;
	d2.Print();
	--d2;
	d2.Print();
	d2--;
	d2.Print();
	d2++;
	d2.Print();
	cout << "---------------------2------------------"<< endl;
	Date d3(2016,1,1);
	d3.Print();
	d3 += 10;
	d3.Print();
	d3 -= 10;
	d3.Print();
	d3 = d3 - 3;
	d3.Print();
	cout << "----------------------3------------------"<< endl;
	bool state;
	Date d4(2016,10,9);
	Date d5(2016,10,10);
	state = d4<d5;
	cout << state << endl;

	cout << "----------------------4------------------"<< endl;

	Date d6(2008,4,1);
	Date d7(2016,1,1);
	cout << d6 - d7<<endl;//2831
	cout << d7 - d6 << endl;

	cout <<" ----------------------5------------------" <<  endl;


	Date d8(1996,10,1);
	cout<<d8<< endl;;
	cin >>d8;
	cout << d8<<endl;
	cout << "----------------------6------------------"<< endl;

	return 0;
}