中國住房和城鄉(xiāng)建設部建造師網(wǎng)站百度推廣云南總代理
文章目錄
- 前言
- 1. 日期的合法性判斷
- 2. 日期+天數(shù)(+/+=)
- 2.1 +和+=的重載
- 2.2 對于兩者復用的討論
- 3. 前置++和后置++重載
- 4. 日期-天數(shù)(-/-=)
- 5. 前置- -和后置- -的重載
- 6. 日期-日期
- 7. 流插入<<重載
- 8. 流提取>>重載
- 9. 總結
- 10. 源碼展示
前言
在上一篇文章我們學習類和對象的過程中,我們不是寫了一個日期類嘛。
但是我們之前實現(xiàn)的日期類并不是很完整,我們只是借助它來幫大家學習類和對象的知識。
那這篇文章呢,我們就在之前的基礎上,再增添一些功能,實現(xiàn)一個比較完整的日期類,作為一個練習,來幫助我們更好的理解我們之前學過的知識。
這是我們之前一起寫的不太完整的日期類:
class Date
{
public://構造函數(shù)Date(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;}//拷貝構造函數(shù)Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}bool operator<(const Date& d){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 operator<=(const Date& d){return *this == d || *this < d;}bool operator>(const Date& d){return !(*this <= d);}bool operator>=(const Date& d){return !(*this < d);}bool operator!=(const Date& d){return !(*this == d);}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}bool operator==(const Date& d){return _year == d._year&& _month == d._month&& _day == d._day;}//賦值重載(對于Date類用默認生成的就行)//d1=d2(this就是d1,d就是d2)/*Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}*/
private:int _year;int _month;int _day;
};
那這些實現(xiàn)過的函數(shù)我們就不再一一講解了,大家不熟悉的話可以回顧一下上一篇文章。
另外呢,我們最終實現(xiàn)的是一個完整的日期類,那方便對代碼進行維護和管理,以及對實現(xiàn)好的日期類進行測試,我們還是像之前寫數(shù)據(jù)結構一樣,放在多個文件中。
1. 日期的合法性判斷
我們之前呢已經給該日期類寫好了構造函數(shù):
Date(int year = 1, int month = 1, int day = 1)
{_year = year;_month = month;_day = day;
}
并且還指定了缺省參數(shù),那這樣的話在實例化一個對象時我們就可以自己給對象指定初值,我們輸入的日期是啥,該對象就會被初始化為對應的日期。
那現(xiàn)在有一個問題,如果我們實例化對象時給的日期不合法呢?比如:
void Datetest1()
{Date d1(2023, 2, 30);d1.Print();
}
不合法是不是也判斷不出來啊。
那我們就對原來的構造函數(shù)做一些補充好吧,讓它在給對象初始化的時候可以去判斷一下對應的日期合不合法。
那要怎么判斷呢?
給我們一個年月日,要判斷是否合法,是不是要判斷月在不在【1,12】之內以及天數(shù)有沒有超過當前月的總天數(shù)啊。
但是某個月的天數(shù)是不是不好確定啊,不同月的天數(shù)不一樣,而且要考慮平閏年。
那我們先來寫一個獲取某年某月天數(shù)的函數(shù):
int Date::GetMonthDay(int year, int month)
{assert(month > 0 && month < 13);int MonthArr[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 MonthArr[month];}
}
不過多解釋了,相信大家都能看懂。
那有了這個函數(shù),我們就可以在構造函數(shù)中去判斷了:
Date::Date(int year, int month, int day)
{if (month > 0 && month < 13 && day>0 && day <= GetMonthDay(year, month)){_year = year;_month = month;_day = day;}else{cout << "日期非法" << endl;_year = 1;_month = 1;_day = 1;}
}
如果合法了,我們再去賦值,不合法就還全搞成1,要不然就是隨機值了。
那這時我們再用非法日期去初始化對象:
這樣輸入的日期不合法就提示了。
2. 日期+天數(shù)(+/+=)
我們說日期+日期是不是沒啥意義啊,但是日期+一個天數(shù)是不是還有點意義,可以理解成這么多天之后是幾幾年幾月幾日。
2.1 +和+=的重載
所以接下來,我們要實現(xiàn)一個功能就是計算一個日期加了一個天數(shù)之后得到的日期:
那具體實現(xiàn)的思路呢可以這樣搞:
首先我們想讓自定義類型Date的對象直接和整型相加,這里肯定要對+
進行運算符重載。
我們拿到一個日期一個天數(shù)之后,先把天數(shù)加到日上,然后,判斷此時的日是否超過了當前月的總天數(shù)(獲取月份天數(shù)的函數(shù)我們之前已經實現(xiàn)過了),超過的話,就減去當前月的天數(shù),然后月份++,那月份++有可能會超過12啊,一旦超過,就讓年++,然后月置成1。
那當然這肯定是一個循環(huán),當我們的日(day)不再大于當前月的天數(shù),則此時得到的就是最終的日期。
我們來寫一下代碼:
Date& Date::operator+(int day)
{_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);_month++;if (_month == 13){_year++;_month = 1;}}return *this;
}
這里*this出了作用域還在,所以可以返回引用。
那我們來測試一下:
我們看這個計算出來的日期確實是沒問題的,但是d1+100,這里是+而不是+=,所以d1是不是不應該變啊,我們只是把d1+100得到的日期賦給了d2,但是現(xiàn)在d1也變了。
所以我們這樣寫其實實現(xiàn)的是啥,是不是+=啊。
所以我們這里重載的應該是+=:
Date& Date::operator+=(int day)
{_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);_month++;if (_month == 13){_year++;_month = 1;}}return *this;
}
那+=還需要有返回值嗎,🆗,最好還是帶返回值,帶返回值的話就可以支持這種情況:
d2 = d1 += 100;
那剛才實現(xiàn)的是+=,那+要這么搞?
是不是借助一個臨時對象就可以搞定了啊,我們只要不改變*this就行了嘛。
Date Date::operator+(int day)
{Date tmp(*this);tmp._day += day;while (tmp._day > GetMonthDay(tmp._year, tmp._month)){tmp._day -= GetMonthDay(tmp._year, tmp._month);tmp._month++;if (tmp._month == 13){tmp._year++;tmp._month = 1;}}return tmp;
}
那就這樣,測試一下:
🆗,這次d1沒有被改變。
答案也沒問題。
那對于+的重載:
大家有沒有注意到我們沒有返回引用,為什么?
因為我們返回的是啥,是不是tmp,而tmp是一個局部的對象,出了作用域就銷毀了,所以我們不能返回引用。
那有時候呢,有的人為了這個地方能夠返回引用,對tmp加了一個static
修飾,然后就返回引用。
大家思考一下這樣可以嗎?
我們試一下會發(fā)現(xiàn):
第一次沒問題,但我們第二次在調用+,是不是就錯了啊。
第二次我們還是給d1+1000天,但結果卻是2000天之后的。
為什么會這樣?
原因就在于我們用了static。
我們創(chuàng)建的局部對象tmp被static修飾后,就不存在棧區(qū)了,而是放在靜態(tài)區(qū)了,所以靜態(tài)局部變量出作用域不會被銷毀,而是保留在靜態(tài)區(qū),因此我們確實可以返回引用了。
但是,靜態(tài)局部變量的初值是在編譯期間就指定的,所以運行期間,不管我們再去調用幾次函數(shù),tmp都不會被重新初始化,而是保留上次的值,所以我們第二次的結果才會變成2000天之后。
之前有篇文章詳解static的作用,大家可以看——鏈接: link
所以呢,這個地方我們不要為了能夠返回引用而去隨便加static。
2.2 對于兩者復用的討論
那除此之外:
大家看,+的重載與+=的重載,除了多一個臨時的局部對象,其它的邏輯是不是一樣啊,所以+里面是不是可以復用+=啊。
Date Date::operator+(int day)
{Date tmp(*this);tmp += day;return tmp;
}
這樣是不是就行了啊:
那既然+可以復用+=,我們是不是也可以考慮先實現(xiàn)+,然后+=復用+呢?
當然可以。
Date Date::operator+(int day)
{Date tmp(*this);tmp._day += day;while (tmp._day > GetMonthDay(tmp._year, tmp._month)){tmp._day -= GetMonthDay(tmp._year, tmp._month);tmp._month++;if (tmp._month == 13){tmp._year++;tmp._month = 1;}}return tmp;
}
那這是我們自己寫的+,現(xiàn)在我們+=來復用+。
Date& Date::operator+=(int day)
{*this = *this + day;return *this;
}
這樣不就行了。
那再來思考:
到底是+復用+=好呢,還是+=復用+好呢?
🆗,那這里呢,其實是我們的第一種即+復用+=更好一點。
因為+里面創(chuàng)建臨時對象有一次拷貝,返回的是值而不是引用又是一次拷貝。
那如果是+復用+=的話就只有+里有拷貝,但如果是+=復用+的話,是不是+=和+里都有拷貝了。
3. 前置++和后置++重載
剛重載了+和+=,那是不是還有前置++和后置++啊,那我們也來實現(xiàn)一下。
先來前置++吧:
來回憶一下前置++的特性是什么?
是不是先++,后使用啊,即返回的是++之后的值。
舉個例子:
int a=5;
int b=++a;
首先不管前置++,還是后置++,a的值肯定都會+1,那現(xiàn)在
++a
前置,先++后使用,返回++之后的值,所以b也是6。
那我們來重載一下:
//前置++
Date& Date::operator++()
{*this += 1;return *this;
}
很簡單,直接復用+=。
那我們再來重載后置++:
后置++呢,是先使用,后++,即返回++之前的值。那我們還是可以借助一個臨時對象。
但是呢?
這里會發(fā)現(xiàn)有一個問題:
前置++和后置++沒法區(qū)分啊,它們的參數(shù)和函數(shù)名是不是一樣啊。
欸,那這怎么解決啊?
🆗,那當然是有辦法的。
前置++和后置++都是一元運算符,為了讓前置++與后置++形成能正確重載。C++規(guī)定:后置++重載時多增加一個int類型的參數(shù),但調用函數(shù)時該參數(shù)不用傳遞(它的作用就是為了構成重載),編譯器自動傳遞。
所以呢,這樣搞就行了。
我們來實現(xiàn)一下:
//后置++
Date Date::operator++(int)
{Date tmp(*this);*this += 1;return tmp;
}
🆗,我們就搞定了。
那實現(xiàn)完了,大家看一下:
前置++和后置++那個效率會高一點。
是不是前置啊,因為與后置相比,前置沒有拷貝啊對不對。
所以,對于內置類型來說,大家可以認為前置后置沒有區(qū)別;但是對于自定義類型來說,能用前置,盡量用前置++。
我們的前置++和后置++就搞定了,那在調用的地方呢,我們正常去用就行了,編譯器會自動識別匹配。
遇到前置++,它就會自動去調用前置++;遇到后置++,編譯器會自動傳一個整型參數(shù),去調用后置++。
4. 日期-天數(shù)(-/-=)
上面我們通過重載+進而實現(xiàn)計算一個日期+一個天數(shù)之后是什么日期,那是不是還可以搞一下日期-天數(shù),計算它的前多少天是什么日期。
那我們先來重載-=:
那思路和上面加一個天數(shù)也是類似的,我們先用日減去傳過來的天數(shù),如果減完之后<=0,說明當前日期是不合法的,那怎么辦,就去加上一個月的天數(shù),然后月–,當然要注意判斷會不會減到上一年,然后還<=0的話,就繼續(xù),知道日>0循環(huán)結束。
Date& Date::operator-=(int day)
{_day -= day;while (_day <= 0){--_month;if (_month == 0){--_year;_month = 12;}_day += GetMonthDay(_year, _month);}return *this;
}
測試一下:
沒問題。
然后我們再重載一下-:
那是不是簡單啊,直接復用-=。
Date Date::operator-(int day)
{Date tmp(*this);tmp -= day;return tmp;
}
測試 一下:
🆗,看起來好像沒什么問題了,但是,如果這樣呢:
這里減一個負數(shù),會發(fā)現(xiàn)結果就錯了。
為什么呢,大家可以調試觀察:
會發(fā)現(xiàn)這里根本不會進入循環(huán),直接就返回了。
所以針對負數(shù)的情況,我們要單獨處理一下:
Date& Date::operator-=(int day)
{if (day < 0){*this += -day;return *this;}_day -= day;while (_day <= 0){--_month;if (_month == 0){--_year;_month = 12;}_day += GetMonthDay(_year, _month);}return *this;
}
我們-是復用-=的,所以這里在-=里面處理。
-=一個-100就相當于+=一個100嘛。
那同樣對于+和+=我們也要處理一下:
那我們來處理一下:
Date& Date::operator+=(int day)
{if (day < 0){*this -= -day;return *this;}_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);_month++;if (_month == 13){_year++;_month = 1;}}return *this;
}
這樣是不是就行了,+=一個-100就相當于-=一個100嘛。
5. 前置- -和后置- -的重載
那有了上面的練習,再實現(xiàn)前置- -和后置- -不是soeasy嘛。
前置- -:
Date& Date::operator--()
{*this -= 1;return *this;
}
先- -,后使用,返回- -之后的值。
后置- -:
Date Date::operator--(int)
{Date tmp(*this);*this -= 1;return tmp;
}
先使用,后- -,返回- -之前的值。
6. 日期-日期
上面我們搞了日期加減天數(shù),那兩個日期相減是不是也有意義啊,可以得出這兩個日期之間差了多少天。
那如何計算兩個日期之間相差的天數(shù)呢?
🆗,那這里給大家提供一種比較好實現(xiàn)的思路:
我們拿到兩個日期之后,先把較小的那個日期找出來,然后用一個計數(shù)器,統(tǒng)計較小日期++的次數(shù),當兩個日期相等時停止,++的次數(shù)就是相差的天數(shù)。
另外如果是第一個日期大于第二個,結果應該是整數(shù);如果第二個大于第一個,應該是負數(shù)。
我們來實現(xiàn)一下:
//日期-日期
int Date::operator-(Date d)
{Date max = *this;Date min = d;int flag = 1;if (*this < d){max = d;min = *this;flag = -1;}int n = 0;while (min != max){++min;++n;}return n * flag;
}
沒有問題。
7. 流插入<<重載
那我們現(xiàn)在打印一個日期類對象的時候是不是都是去調用我們寫的
使用我們之前學的cout
+<<
去打印。
大家記不記得:
我們之前文章里學習C++輸入輸出的時候,其實只是淺淺的提了一下如何去用,并沒有對cout、<<和>>進行過多講解。
因為以我們那時的知識儲備還不能很好的理解:
那我們現(xiàn)在就可以再嘗試多理解一點東西:
我們發(fā)現(xiàn)我們的自定義類型想用這些運算符是不是都要重載啊,除了賦值運算符以及取地址運算符,因為賦值重載和取地址重載是類的6個默認成員函數(shù)之中的,我們不寫編譯器會自動生成一個。但是在有些情況下根據(jù)實際情況我們還是需要自己寫。
🆗,這是我們上一篇學習的知識,不用過多說明了。
然后呢我們還說C++里這樣輸入輸出可以自動識別類型。
那為啥可以自動識別類型,其實是因為它這里對
<<
進行了函數(shù)重載。
為什么我們的內置類型可以直接用,因為庫里面已經對這些類型都進行了重載,所以可以自動識別類型,是根據(jù)操作數(shù)的不同類型進行匹配。
那我們現(xiàn)在自定義類型想用怎么辦,是不是需要自己重載啊。
那我們接下來就重載一下<<
好吧:
void operator<<(ostream& out);
那想用
<<
是不是得使用cout
,<<
兩個操作數(shù),一個cout,一個是我們要打印得對象,cout
是啥?
🆗,上面說了它是一個ostream
類型得對象,所以我們把cout
作為參數(shù)傳過去。
那這里out就用來接收cout,this指針指向得就是我們要打印得類對象。
來實現(xiàn)一下:
void Date::operator<<(ostream& out)
{out << _year << _month << _day << endl;
}
這樣是不是就行了啊,它的成員變量都是內置類型,我們就可以使用<<直接打印了。
我們測試一下:
但是我們使用的時候發(fā)現(xiàn)報錯了。
這里操作數(shù)是不是寫反了,為什么?
對于函數(shù)重載來說,兩個參數(shù)的話,第一個參數(shù)是左操作數(shù),第二個參數(shù)是右操作數(shù)。
但是對于類成員函數(shù)來說,第一個參數(shù)是不是隱藏的this指針啊,它指向我們調用該函數(shù)的對象,所以這里第一個參數(shù)是Date對象的地址。
那我們要調用的話,應該這樣寫:
但是這樣寫是不是好別扭啊。
怎么讓它像內置類型那樣使用啊。
那我們就要想辦法讓cout成為第一個參數(shù),怎么做呢?
把函數(shù)重載寫到類外面不就行了是吧。
沒有說運算符重載不能寫到類外面啊,我們寫到類里面是為了啥,是不是只是為了可以訪問private修飾的成員變量啊
那我們現(xiàn)在重載到外面:
那現(xiàn)在面臨的問題是啥?
是在類外不能訪問私有的成員變量,那怎么辦?
可以把成員變量變成共有的public,但這樣是不是就不能很好的保證封裝性了;
或者可以提供Get方法,但C++一般不喜歡這樣搞。
那還有什么方法呢?
🆗,就是用友元函數(shù)。
那怎么做呢?
我們把函數(shù)聲明再放到類里面一份,但在前面加一個friend就行了:
那這下我們就可以正常使用<<了:
但是呢:
這里不支持連續(xù)的流插入。為什么呢?
因為我們重載的沒有返回值
那應該返回啥?
是不是返回cout呀,讓它能夠繼續(xù)打印后面的。
我們看其實庫里面就是這么搞的:
ostream& operator<<(ostream& out, Date& d)
{out << d._year << "-" << d._month << "-" << d._day << endl;return out;
}
這樣就行了。
8. 流提取>>重載
那緊接著,我們再來重載一下流提取:
istream& operator>>(istream& in, Date& d)
{in >> d._year >> d._month >> d._day;return in;
}
測試一下:
就完成了。
9. 總結
那最后呢,還要給大家說明一點:
我們在之前的類和對象第一篇其實就提到了:
就是類的成員函數(shù)如果直接定義在類里面,編譯器是會將其當成內聯(lián)函數(shù)的,不管你有沒有加inline關鍵字。
那我們在學習內聯(lián)函數(shù)的時候也說了:
一般建議將函數(shù)規(guī)模較小(即函數(shù)不是很長,具體沒有準確的說法,取決于編譯器內部實現(xiàn))、不是遞歸、且頻繁調用的函數(shù)實現(xiàn)成內聯(lián)函數(shù)。
所以說,類里面的成員函數(shù)如果規(guī)模較小,適合做內聯(lián)函數(shù)的,直接定義在類里面。
不過我們今天寫的這個日期類,里面我是所有成員函數(shù)的聲明和定義都分離了,大家以后可以根據(jù)實際情況,有些成員函數(shù)直接定義在類里面。
但是我們說了內聯(lián)函數(shù)不是只是對編譯器的一個建議嘛,如果規(guī)模較大的函數(shù)就算我們實現(xiàn)成內聯(lián)函數(shù)編譯器也不一定按照內聯(lián)函數(shù)處理。
那在類里面也是這樣,就算我們把全部的類成員函數(shù)都直接定義在類里面,也不一定會全部當做內聯(lián)函數(shù)處理,編譯器也還是會看它具體適不適合做內聯(lián)。
另外還有一點:
上一篇文章我們不是還學習了const成員函數(shù)嘛,大家還可以看一看我們日期類的這么多成員函數(shù),哪一個在函數(shù)內部不需要改變調用它的對象,是不是把它實現(xiàn)成const成員函數(shù)也是比較好的。
10. 源碼展示
最后,把完整的源碼給大家展示一下:
- Date.h
#pragma once
#include <iostream>
#include <stdbool.h>
#include <assert.h>
using namespace std;class Date
{//友元friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);public:int GetMonthDay(int year, int month);//構造函數(shù)Date(int year = 1, int month = 1, int day = 1);//拷貝構造函數(shù)//Date(const Date& d);bool operator<(const Date& d);bool operator<=(const Date& d);bool operator>(const Date& d);bool operator>=(const Date& d);bool operator!=(const Date& d);void Print();bool operator==(const Date& d);Date& operator+=(int day);Date operator+(int day);//前置++Date& operator++();//后置++Date operator++(int);Date& operator-=(int day);Date operator-(int day);Date& operator--();Date operator--(int);//日期-日期int operator-(Date d);//賦值重載(對于Date類用默認生成的就行)//d1=d2(this就是d1,d就是d2)/*Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}*/
private:int _year;int _month;int _day;
};
//<<
ostream& operator<<(ostream& out, const Date& d);
istream& operator>>(istream& in, Date& d);
- Date.cpp
#define _CRT_SECURE_NO_WARNINGS
#include "Date.h"int Date::GetMonthDay(int year, int month)
{assert(month > 0 && month < 13);int MonthArr[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 MonthArr[month];}
}
//構造函數(shù)
Date::Date(int year, int month, int day)
{if (month > 0 && month < 13 && day>0 && day <= GetMonthDay(year, month)){_year = year;_month = month;_day = day;}else{cout << "日期非法" << endl;_year = 1;_month = 1;_day = 1;}
}
//拷貝構造函數(shù)
//Date::Date(const Date& d)
//{
// _year = d._year;
// _month = d._month;
// _day = d._day;
//}
bool Date::operator<(const Date& d)
{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)
{return *this == d || *this < d;
}
bool Date::operator>(const Date& d)
{return !(*this <= d);
}
bool Date::operator>=(const Date& d)
{return !(*this < d);
}
bool Date::operator!=(const Date& d)
{return !(*this == d);
}
void Date::Print()
{cout << _year << "-" << _month << "-" << _day << endl;
}
bool Date::operator==(const Date& d)
{return _year == d._year&& _month == d._month&& _day == d._day;
}//Date Date::operator+(int day)
//{
// Date tmp(*this);
// tmp._day += day;
// while (tmp._day > GetMonthDay(tmp._year, tmp._month))
// {
// tmp._day -= GetMonthDay(tmp._year, tmp._month);
// tmp._month++;
// if (tmp._month == 13)
// {
// tmp._year++;
// tmp._month = 1;
// }
// }
// return tmp;
//}
//
//Date& Date::operator+=(int day)
//{
// *this = *this + day;
// return *this;
//}Date& Date::operator+=(int day)
{if (day < 0){*this -= -day;return *this;}_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);_month++;if (_month == 13){_year++;_month = 1;}}return *this;
}Date Date::operator+(int day)
{Date tmp(*this);tmp += day;return tmp;
}//前置++
Date& Date::operator++()
{*this += 1;return *this;
}
//后置++
Date Date::operator++(int)
{Date tmp(*this);*this += 1;return tmp;
}
Date& Date::operator-=(int day)
{if (day < 0){*this += -day;return *this;}_day -= day;while (_day <= 0){--_month;if (_month == 0){--_year;_month = 12;}_day += GetMonthDay(_year, _month);}return *this;
}
Date Date::operator-(int day)
{Date tmp(*this);tmp -= day;return tmp;
}Date& Date::operator--()
{*this -= 1;return *this;
}
Date Date::operator--(int)
{Date tmp(*this);*this -= 1;return tmp;
}
//日期-日期
int Date::operator-(Date d)
{Date max = *this;Date min = d;int flag = 1;if (*this < d){max = d;min = *this;flag = -1;}int n = 0;while (min != max){++min;++n;}return n * flag;
}
//<<
ostream& operator<<(ostream& out, const Date& d)
{out << d._year << "-" << d._month << "-" << d._day << endl;return out;
}
istream& operator>>(istream& in, Date& d)
{in >> d._year >> d._month >> d._day;return in;
}
- Test.cpp
#define _CRT_SECURE_NO_WARNINGS
#include "Date.h"void Datetest1()
{Date d1(2023, 2, 15);d1.Print();Date d2 = d1 + (-100);d2.Print();/*Date d3 = ++d1;d3.Print();*/
}
void Datetest2()
{Date d1(2023, 2, 16);d1.Print();Date d2 = d1--;d1.Print();d2.Print();}
void Datetest3()
{Date d1;cin >> d1;cout << d1 << endl;}
int main()
{//Datetest3();return 0;
}
🆗,那這篇文章就到這里,歡迎大家指正!!!
下一篇文章,我們會對類和對象再做一些補充和收尾!!!