類的預設成員函式---都是原始碼
阿新 • • 發佈:2018-12-11
class Date { public: //沒用初始化列表 Date(int year = 1999,int month = 1,int day = 1)//最好定義為全預設 { //檢查日期是否合法 if(year < 1900 || month < 1 || month > 12 || day < 1 || day > GetMonthDay(year,month)) { cout<<"非法日期"<<endl; } _year = year; _month = month; _day = day; } Date(const Date& d) { _year = d._year; _month = d._month; _day = d._day; } //d2 = d3 => d2.operator(&d2,d3) Date& operator=(const Date& d) //有倆個引數,但只寫一個,因為還有一個引數是隱含的this指標。 { if(this != &d) //是否是自己給自己賦值。沒有什麼很壞的影響,只是白做了而已。 { this->_year = d._year; //this可以顯示的寫出來,也可以不寫,寫著this在這裡方便於觀察。 this->_month = d._month; this->_day = d._day; } return *this; //賦值操作已經完成,為什麼有個返回值?因為賦值運算子的過載支援三個數,i=j=k;k先賦給j後有一個返回值j,將這個返回值賦給i,返回的是同類型物件,所以型別為Date //但此時如果沒有給函式型別加引用,就是傳值返回,不會直接返回,會建立一個臨時物件。。會多一次拷貝構造,拷貝一個臨時物件,再拿這個臨時物件做返回 //傳值返回:返回的是一個臨時物件 //傳引用返回:返回的物件出了作用域還在 } //d1 < d2 會先去全域性區找有沒有小於的運算子過載,沒有的話就到類中找,找到了,其實就轉化為->d1.operator<(&d1,d2) //bool operator<(const Date& x1) //在類外面我們實現了第一次的operator,對類外進行改進 // { // if(_year < x1._year) // { // return true; // } // else if(_year == x1._year) // { // if(_month < x1._month) // { // return true; // } // else if(_month == x1._month) // { // if(_day < x1._day) // return true; // } // } // return false; // } //d1+10 //Date operator+(int day) //自己寫的 //{ // /*int day = day + _day; // while(day > GetMonthDay(_year,_month)) // { // day = day - GetMonthDay(_year,_month); // _month++; // if(_month > 12) // { // _year++; // _month = 1; // _day = 1; // } // } // return *this;*/ //} //Date operator+(int day) //{ // Date ret(*this); //+運算子不能改變原有的this的值,所以需要一個臨時變數和this有相同的空間和值。 // // ret._day += day; // while(ret._day > GetMonthDay(ret._year,ret._month)) // { // ret._day -= GetMonthDay(ret._year,ret._month); // ret._month++; // if(ret._month == 13) // { // ret._year++; // ret._month = 1; // } // } // return ret; //返回一個臨時變數,所以用傳值返回。 //} ////d1 += 10 //Date& operator+=(int day) //{ // *this = *this + day; //調一次+再調一次賦值 // return *this; //這樣的前提是先實現+,但是先實現+=好,因為+裡既拷貝還要開空間還要賦值 //} Date& operator+=(int day) { if(day < 0) { return *this -= -day; } _day += day; while(_day > GetMonthDay(_year,_month)) { _day -= GetMonthDay(_year,_month); _month++; if(_month == 13) { _year++; _month = 1; } } return *this; } //d+10 Date operator+(int day) { Date ret(*this);//*this 是d ret += day; return ret; } //自己寫的 /*Date operator-(int day) { Date ret(*this); ret._day = day - ret._day; while(ret._day > GetMonthDay(ret._year,ret._month)) { ret._day = ret._day - GetMonthDay(ret._year,ret._month); ret._month--; if(ret._month == 0) { ret._year--; ret._month = 12; } } return ret; } Date& operator-=(int day) { *this = *this - day; return *this; }*/ //上課 /*Date operator-(int day) { Date ret(*this); ret._day -= day; while(ret._day <= 0) { ret._month--; ret._day += GetMonthDay(ret._year,ret._month); if(ret._month == 0) { ret._year--; ret._month = 12; } } return ret; }*/ Date& operator-=(int day) { if(day < 0) { return *this += -day; } _day -= day; while(_day <= 0) { --_month; if(_month == 0) { _year--; _month = 12; } _day+=GetMonthDay(_year,_month); } return *this; } Date operator-(int day) { Date ret(*this); ret -= day; return ret; } //d1 -d2 int operator-(const Date& d) //不加const d2會被改 { int flag = 1; Date max = *this; Date min = d; if(*this < d) { max = d; min = *this; flag = -1; } int day = 0; while(min < max) { ++(min); ++day; } return day*flag; } //++d => d.operator++(&d) Date& operator++() //前置 返回值是++後的值 { *this += 1; return *this; } //d++ => operator++(&d,0) Date operator++(int) //後置 int只是為了與前置做一個區分 返回的是++前的值 { Date ret(*this); *this += 1; return ret; } Date& operator--() { *this -= 1; return *this; } Date operator--(int) { Date ret(*this); *this -= 1; return ret; } bool operator>(const Date& d) { if(_year > d._year) { return true; } else if(_year == d._year) { if(_month > d._month) { return true; } else if(_month == d._month) { if(_day > d._day) return true; } } return false; } bool operator==(const Date& d) { return _year == d._year && _month == d._month &&_day == d._day; } 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); } //~Date() //這個日期類可以不去清理,但有的類需要清理,比如順序表 //{ // //清理工作 // cout<<"~Date()"<<endl; //} void Display() { cout<<_year<<"-"<<_month<<"-"<<_day<<endl; } int GetMonthDay(int year,int month) { static int MonthDay[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; int day = MonthDay[month]; if(month == 2 && ((year%400 == 0) || (year%4 == 0 && year%100 != 0))) { day += 1; } return day; } private: int _year; int _month; int _day; }; //bool operator<(const Date& x1,const Date& x2) //要穿引用返回;如果傳值雖然不會無窮遞迴,但傳值代價大,要開闢空間還要調拷貝建構函式。 // //並且比較完不會改變x1x2所以最好加一個const //引用做引數提高效率,提高效能 // //這個函式之所以完成,是因為吧成員變數定義為了公有,但公有會破壞C++封裝性,可是定義為私有我這個函式就跑不了。。在類外不可訪問,那就放在類中 // //但直接放在類中又有錯誤:operator<的引數太多 //{ // if(x1._year < x2._year) // { // return true; // } // else if(x1._year == x2._year) // { // if(x1._month < x2._month) // { // return true; // } // else if(x1._month == x2._month) // { // if(x1._day < x2._day) // return true; // } // } // return false; //} void test() { Date d1(2018,9,20); Date d2(2019,2,28); d2.Display(); cout<<d2-d1<<endl; /*d1 = d2 - 20; d1.Display(); (++d1).Display(); (d1++).Display(); (--d2).Display(); (d2--).Display();*/ //Date d2(2018,2,2); // // //cout<<d1.operator<(d2)<<endl; //(<<優先順序高於<) ////cout<<operator<(d1,d2)<<endl; //d2 = d1; //d2.Display(); //Date d2(2018,2,29); }