最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++實現(xiàn)日期類的示例詳解

 更新時間:2023年02月07日 14:15:10   作者:rygttm  
這篇文章主要為大家詳細(xì)介紹了四個C++常用的日期類的實現(xiàn),文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C++有一定的幫助,需要的可以參考一下

一、獲取某年某月的天數(shù)

1.在實現(xiàn)日期類的過程中,日期加減天數(shù)的應(yīng)用場景一定會頻繁使用到這個函數(shù)接口,因為加減天數(shù)會使得月份發(fā)生變化,可能增月或減月,這個時候就需要在day上面扣除或增加當(dāng)年當(dāng)月的天數(shù),所以這個接口非常的重要。

2.為了方便獲取到某年某月的天數(shù),我們將數(shù)組大小設(shè)置為13,以便月份能夠和數(shù)組中的下標(biāo)對應(yīng)上,并且我們將數(shù)組設(shè)置為靜態(tài),就不需要考慮每次調(diào)用函數(shù)建立棧幀后重新給數(shù)組分配空間的事情了,因為數(shù)組一直被存放在靜態(tài)區(qū)。

3.四年一閏,百年不閏,四百年一閏,閏年或平年會影響2月份的天數(shù),所以我們要將這種情況單拉出來進(jìn)行處理分析。

int GetMonthDay(int year, int month)
    {
        static int monthDayArray[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
        if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
        {
            return 29;
        }
        else
        {
            return monthDayArray[month];
        }
    }

二、Date的默認(rèn)成員函數(shù)(全缺省的默認(rèn)構(gòu)造)

1.編譯器默認(rèn)生成的構(gòu)造函數(shù)不會處理內(nèi)置類型,所以我們需要自己去寫構(gòu)造函數(shù),非常推薦大家使用全缺省的構(gòu)造函數(shù),編譯器對自定義類型會自動調(diào)用該類類型的默認(rèn)構(gòu)造。

2.由于Date類的成員變量都是內(nèi)置類型,所以析構(gòu)函數(shù)不需要我們自己寫,因為沒有資源的申請。并且拷貝構(gòu)造和賦值重載也不需要寫,因為Date類不涉及深拷貝的問題,僅僅使用淺拷貝就夠了。

3.至于取地址重載和const對象取地址重載,本身就不需要我們寫。

除非你不想讓別人通過取地址符號&來拿到實例化對象的地址,那可以返回nullptr,來屏蔽別人通過&拿到對象地址,但極大概率沒人這么做。

Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;

		// 檢查日期是否合法
		if (!(year >= 1&& (month >= 1 && month <= 12)&& (day >= 1 && day <= GetMonthDay(year, month))))
		{
			cout << "非法日期" << endl;
		}
	}

三、運算符重載

1.+ =、+、- =、-

1.實現(xiàn)+ =或 - =之后,就不需要實現(xiàn)+ -的重載了,我們可以調(diào)用之前實現(xiàn)過的成員函數(shù),需要注意的是形參day有可能是負(fù)數(shù),對于這種情況可以將其交給+=或-=對方來處理這種情況,因為這兩個運算符正好是反過來的,可以處理對方day為負(fù)數(shù)的時候的情況。

2.+=實現(xiàn)的思路就是,實現(xiàn)一個循環(huán),直到天數(shù)回到該月的正常天數(shù)為止,在循環(huán)內(nèi)部要做的就是進(jìn)月和進(jìn)年,讓天數(shù)不斷減去本月天數(shù),直到恢復(fù)本月正常天數(shù)時,循環(huán)結(jié)束,返回對象本身即可。

3.-=實現(xiàn)的思路就是,實現(xiàn)一個循環(huán),直到天數(shù)變?yōu)檎龜?shù)為止,在循環(huán)內(nèi)部要做的就是借月和借年,讓天數(shù)不斷加上上一個月份的天數(shù),直到恢復(fù)正數(shù)為止,循環(huán)結(jié)束,返回對象本身。

Date& Date::operator+=(int day)
{
	if (day < 0)
	{
		return *this -= abs(day);
	}

	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		++_month;

		if (_month == 13)
		{
			_month = 1;
			++_year;
		}
	}
	return *this;
}
Date Date::operator+(int day)
{
	Date ret(*this);
	ret += day;
	return ret;
}

Date& Date::operator-=(int day)
{
	if (day < 0)
	{
		return *this += abs(day);
	}

	_day -= day;
	while (_day <= 0)
	{
		--_month;
		if (_month == 0)
		{
			_month = 12;
			--_year;
		}
		_day += GetMonthDay(_year, _month);

	}
	return *this;
}
Date Date::operator-(int day)
{
	Date ret(*this);
	ret -= day;
	return ret;
}

2.==、!=、>、>=、<、<=

1.下面這些比較運算符的重載應(yīng)該是非常簡單的了,只需要實現(xiàn)一半的運算符重載即可,剩余運算符利用反邏輯操作符!即可輕松實現(xiàn)。

bool Date::operator==(const Date& d)const
{
	return _year == d._year && _month == d._month && _day == d._day;
}

bool Date::operator>(const Date& d) const
{
	if (_year > d._year)
	{
		return true;
	}
	else if (_year == d._year && _month >> d._month)
	{
		return true;
	}
	else if (_year == d._year && _month == d._month && _day > d._day)
	{
		return true;
	}

	return false;
}

bool Date::operator>=(const Date& d) const
{
	return *this > d || *this == d;
}
bool Date::operator<=(const Date& d) const
{
	return !(*this > d);
}
bool Date::operator<(const Date& d) const
{
	return !(*this >= d);
}
bool Date::operator!=(const Date& d) const
{
	return !(*this == d);
}

3.前置++、–、后置++、–

1.實現(xiàn)前置和后置的區(qū)別就是,一個返回臨時對象,一個返回對象本身,在實現(xiàn)+=和-=以及+ -這些運算符重載之后,自增或自減運算符的重載非常簡單了,也是直接套用即可。

Date& Date::operator++()
{
	return *this += 1;
}
Date Date::operator++(int)
{
	Date ret(*this);
	*this += 1;
	return ret;
}

Date& Date::operator--()
{
	return *this -= 1;
}
Date Date::operator--(int)
{
	Date ret(*this);

	*this -= 1;

	return ret;
}

4.<<流插入、>>流提?。▋?nèi)聯(lián)的<<、>>重載函數(shù))

1.流插入和流提取不適用于在類內(nèi)部實現(xiàn),因為隱含的this指針會先搶到第一個參數(shù)位置,而我們又習(xí)慣將cout作為左操作數(shù)使用,這就產(chǎn)生了沖突,所以我們需要將重載放到全局位置,并且我們很可能頻繁使用這兩個重載,所以最好搞成內(nèi)聯(lián)函數(shù)。

2.起始流插入和流提取的重載非常簡單,本質(zhì)上就是利用了庫中實現(xiàn)的類的實例化對象cin和cout,他們完全支持輸出編譯器的內(nèi)置類型,而所有的自定義類型實際上都是內(nèi)置類型堆砌而成,我們只需要在重載中將對象的內(nèi)置類型一個個的輸出即可,這就是對象的流插入和流提取的本質(zhì)思想。

inline ostream& operator<<(ostream& out, const Date& d)
{
    out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
    return out;
}
inline istream& operator>>(istream& in,  Date& d)
{
    in >> d._year >> d._month >> d._day;
    return in;
}

四、兩個日期相減,返回天數(shù)

1.這個模塊的實現(xiàn)非常的有意思,利用了一個編程技巧假設(shè),我們不知道哪個對象的日期更大一些,那我們就先假設(shè)一下,如果判斷錯誤,只要糾正一下即可。
然后定義一個計數(shù)器,讓較小日期自增,直到和較大日期相等為止,最后的計數(shù)器就是日期之間相差的天數(shù),這個天數(shù)既有可能是正,也有可能是負(fù),所以這里利用了flag標(biāo)志位,返回flag和cnt的乘積。

int Date::operator-(const Date& d)const
{
	Date max = *this;
	Date min = d;
	int flag = 1;
	if (*this < d)
	{
		max = d;
		min = *this;
		flag = -1;
	}

	int cnt = 0;
	while (min != max)
	{
		++min;
		++cnt;
	}
	return cnt * flag;
}

五、日期類完整代碼

1.Date.h

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

class Date
{
public:
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& in,  Date& d);
	
	int GetMonthDay(int year, int month)
	{
		//靜態(tài)數(shù)組,每次調(diào)用不用頻繁在棧區(qū)創(chuàng)建數(shù)組
		static int monthDayArray[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
		if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)))
		{
			return 29;
		}
		else
		{
			return monthDayArray[month];
		}
	}
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;

		// 檢查日期是否合法
		if (!(year >= 1&& (month >= 1 && month <= 12)&& (day >= 1 && day <= GetMonthDay(year, month))))
		{
			cout << "非法日期" << endl;
		}
	}
	//拷貝構(gòu)造、賦值重載、析構(gòu)函數(shù)都不用自己寫
	
	void Print()const 
	{
		cout << _year << "年" << _month << "月" << _day << "日" << endl;
	}

	bool operator==(const Date& d)const;

	bool operator>(const Date& d) const;
	
	bool operator>=(const Date& d) const;
	bool operator<=(const Date& d) const;
	bool operator<(const Date& d) const;
	bool operator!=(const Date& d) const;

	Date& operator+=(int day);
	Date operator+(int day);

	Date& operator-=(int day);
	Date operator-(int day);

	Date& operator++();//前置++
	Date operator++(int);//后置++

	Date& operator--();//前置--
	Date operator--(int);//后置--

	// d1 - d2;
	int operator-(const Date& d)const;

private:
	int _year;
	int _month;
	int _day;
};

inline ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
	return out;
}
inline istream& operator>>(istream& in,  Date& d)
{
	in >> d._year >> d._month >> d._day;
	return in;
}

2.Date.cpp

#include "Date.h"


bool Date::operator==(const Date& d)const
{
	return _year == d._year && _month == d._month && _day == d._day;
}

bool Date::operator>(const Date& d) const
{
	if (_year > d._year)
	{
		return true;
	}
	else if (_year == d._year && _month >> d._month)
	{
		return true;
	}
	else if (_year == d._year && _month == d._month && _day > d._day)
	{
		return true;
	}

	return false;
}

bool Date::operator>=(const Date& d) const
{
	return *this > d || *this == d;
}
bool Date::operator<=(const Date& d) const
{
	return !(*this > d);
}
bool Date::operator<(const Date& d) const
{
	return !(*this >= d);
}
bool Date::operator!=(const Date& d) const
{
	return !(*this == d);
}

Date& Date::operator+=(int day)
{
	if (day < 0)
	{
		return *this -= abs(day);
	}

	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		++_month;

		if (_month == 13)
		{
			_month = 1;
			++_year;
		}
	}
	return *this;
}
Date Date::operator+(int day)
{
	Date ret(*this);
	ret += day;
	return ret;
}

Date& Date::operator-=(int day)
{
	if (day < 0)
	{
		return *this += abs(day);
	}

	_day -= day;
	while (_day <= 0)
	{
		--_month;
		if (_month == 0)
		{
			_month = 12;
			--_year;
		}
		_day += GetMonthDay(_year, _month);

	}
	return *this;
}
Date Date::operator-(int day)
{
	Date ret(*this);
	ret -= day;
	return ret;
}

Date& Date::operator++()
{
	return *this += 1;
}
Date Date::operator++(int)
{
	Date ret(*this);
	*this += 1;
	return ret;
}

Date& Date::operator--()
{
	return *this -= 1;
}
Date Date::operator--(int)
{
	Date ret(*this);

	*this -= 1;

	return ret;
}


int Date::operator-(const Date& d)const
{
	Date max = *this;
	Date min = d;
	int flag = 1;
	if (*this < d)
	{
		max = d;
		min = *this;
		flag = -1;
	}

	int cnt = 0;
	while (min != max)
	{
		++min;
		++cnt;
	}
	return cnt * flag;
}

3.Test.cpp

#include "Date.h"


void TestDate1()
{
	Date d1(2022, 10, 8);
	Date d3(d1);
	Date d4(d1);

	d1 -= 10000;
	d1.Print();

	Date d2(d1);
	/*Date d3 = d2 - 10000;
	d3.Print();*/
	(d2 - 10000).Print();
	d2.Print();

	d3 -= -10000;
	d3.Print();

	d4 += -10000;
	d4.Print();
}

void TestDate2()
{
	Date d1(2022, 10, 8);
	Date d2(d1);
	Date d3(d1);
	Date d4(d1);

	(++d1).Print(); // d1.operator++()
	d1.Print();

	(d2++).Print(); // d2.operator++(1)
	d2.Print();


	(--d1).Print(); // d1.operator--()
	d1.Print();

	(d2--).Print(); // d2.operator--(1)
	d2.Print();
}

void TestDate3()
{
	Date d1(2022, 10, 10);
	Date d2(2023, 7, 1);

	cout << d2 - d1 << endl;
	cout << d1 - d2 << endl;
}

void TestDate4()
{
	Date d1, d2;
	

	cin >> d1 >> d2;
	cout << d1 << d2 << endl; // operator<<(cout, d1);
	cout << d1 - d2 << endl;
}


int main()
{
	//TestDate1();
	TestDate4();
	return 0;
}

以上就是C++實現(xiàn)日期類的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于C++日期類的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

甘德县| 鸡西市| 大化| 陆河县| 镇江市| 萨迦县| 依兰县| 西华县| 中卫市| 千阳县| 屏东市| 德令哈市| 克东县| 临武县| 涪陵区| 曲松县| 元谋县| 镇远县| 察隅县| 犍为县| 西华县| 福建省| 洛阳市| 郎溪县| 德清县| 新民市| 舒兰市| 江城| 庆阳市| 泸水县| 惠东县| 高淳县| 山东| 汨罗市| 石楼县| 左贡县| 普宁市| 柳河县| 洞口县| 博野县| 清丰县|