?前言:大家好,這里是YY;此篇博客主要是操作符重載的應用;包含【流插入,流提取】【>,<,>=,<=,】【+,-,+=,-=】【前置++,后置++,前置--,后置--】
PS:最后的模塊有完整代碼演示;如果對你有幫助,希望能夠關注,贊,收藏,謝謝!?
目錄
一.流插入,流提取?
1.為什么流插入<<不能寫成成員函數(shù)?
2.流插入寫在類外訪問類內成員的方法——友元
3.代碼展示:??
二.基本運算符重載【>,>=,<,<=等】?
1.代碼展示:??
三.基本運算符重載【+,+=,-,-=】(日期與天數(shù)的運算)
1.代碼展示:??
四.基本運算符重載【前置++,后置++等】
1.機制說明:
1.如何設置返回類型?
2.如何在定義與聲明中區(qū)分前后置?
2.代碼展示:?
五. 減法的重載(日期-日期)
六.完整代碼實現(xiàn)?
一.流插入,流提取?
?【流插入的庫是在iostream里,流提取的庫是在ostream里】
- 可以支持內置類型是因為在庫里面實現(xiàn)了
- 可以支持自定義類型,是因為人為進行了函數(shù)重載
圖示:
此時:cout<<d相當于count.operator(d)
1.為什么流插入<<不能寫成成員函數(shù)?
// 流插入不能寫成成員函數(shù)? //因為Date對象默認占用第一個參數(shù),就是做了左操作數(shù) 如果按照正常使用場景實現(xiàn)出來: count<<d1; 如果寫在成員函數(shù)里會表現(xiàn)出 count.operator<<(d) 訪問不了成員 只有寫成 d1 << cout; 才會在成員函數(shù)里表現(xiàn)出 d1.operator<<(count) 才能進行傳參,訪問成員
?因此為了使用操作合乎習慣,又要讓流插入能夠訪問成員,只能將流插入重載寫在類外(雖然流提取不會出現(xiàn)這種情況,為了統(tǒng)一,一并寫在類外)
2.流插入寫在類外訪問類內成員的方法——友元
但是類內的成員是private(私有的),我們可以通過友元(聲明操作符重載函數(shù)能進入類內訪問的權限)
3.代碼展示:??
頭文件部分:?
#pragma once #include<iostream> #include<assert.h> using namespace std; class Date { // 友元函數(shù)聲明 friend ostream& operator<<(ostream& out, const Date& d); friend istream& operator>>(istream& in, Date& d); public: Date(int year = 1, int month = 1, int day = 1); void Print() const { cout << _year << "-" << _month << "-" << _day << endl; } Date(const Date& d) // 錯誤寫法:(不加引用)編譯報錯,會引發(fā)無窮遞歸 { // 拷貝構造 _year = d._year; _month = d._month; _day = d._day; } int GetMonthDay(int year, int month); private: int _year; int _month; int _day; }; //雖然友元已經聲明,但那與函數(shù)聲明不同,僅是表示權限 //這里還是要再次進行函數(shù)聲明 ostream& operator<<(ostream& out, const Date& d); istream& operator>>(istream& in, Date& d);
.c文件部分:?
ostream& operator<<(ostream& out, const Date& d) { out << d._year << "年" << d._month << "月" << d._day << "日" << endl; return out; } istream& operator>>(istream& in, Date& d) { int year, month, day; in >> year >> month >> day; if (month > 0 && month < 13 && day > 0 && day <= d.GetMonthDay(year, month)) { d._year = year; d._month = month; d._day = day; } else { cout << "非法日期" << endl; assert(false); } return in; }
二.基本運算符重載【>,>=,<,<=等】?
1.代碼展示:??
類內聲明:
PS:加const,可以讓普通變量和const變量都能調用該函數(shù)(具體知識點可見YY的C++知識合集博客,關于const的解讀)
bool operator<(const Date& x) const; //相當于bool operator<(const Date* const this,const Date& x);,下列聲明同理 bool operator==(const Date& x) const; bool operator<=(const Date& x) const; bool operator>(const Date& x) const; bool operator>=(const Date& x) const; bool operator!=(const Date& x) const;
.c文件實現(xiàn):?
PS:在函數(shù)實現(xiàn)過程中可以使用技巧"復用"
(多個函數(shù)只需要復用一個定義即可,具體代碼)
bool Date::operator==(const Date& x) const { return _year == x._year && _month == x._month && _day == x._day; } bool Date::operator<(const Date& x) const { if (_year < x._year) { return true; } else if (_year == x._year && _month < x._month) { return true; } else if (_year == x._year && _month == x._month && _day < x._day) { return true; } return false; } //直接利用一個<的復用完成其他定義 bool Date::operator<=(const Date& x) const { return *this < x || *this == x; } bool Date::operator>(const Date& x) const { return !(*this <= x); } bool Date::operator>=(const Date & x) const { return !(*this < x); } bool Date::operator!=(const Date& x) const { return !(*this == x); }
三.基本運算符重載【+,+=,-,-=】(日期與天數(shù)的運算)
1.代碼展示:??
類內聲明:
PS:加const,可以讓普通變量和const變量都能調用該函數(shù)(具體知識點可見YY的C++知識合集博客,關于const的解讀)
PS:const加在后面表示const Date* this ;表明在該成員函數(shù)中不能對類的任何成員進行修改,而+=,-=是要實現(xiàn)對類內成員的改變,因此不能加;
Date& operator+=(int day); Date operator+(int day) const; Date& operator-=(int day); Date operator-(int day) const;
.c文件實現(xiàn):?
Date& 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; } // d1 + 100 Date Date::operator+(int day) const { //復用+= Date tmp(*this); tmp += day; return tmp; /*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) { if (day < 0) { return *this += -day; } _day -= day; while (_day <= 0) { --_month; if (_month == 0) { _month = 12; --_year; } _day += GetMonthDay(_year, _month); } return *this; } Date Date::operator-(int day) const { Date tmp = *this; tmp -= day; return tmp; }
四.基本運算符重載【前置++,后置++等】
1.機制說明:
1.如何設置返回類型?
- 前置的是【先賦值后使用】:返回的是本身(Date&接收)(引用提高效率)
- 后置的是【先使用后賦值】:返回的是臨時變量(Date接收)(不用引用,因為臨時變量出作用域即銷毀,引用會變成野引用)
2.如何在定義與聲明中區(qū)分前后置?
- ?增加參數(shù)int,構成函數(shù)重載
2.代碼展示:?
類內聲明:
//增加這個int參數(shù)不是為了接收具體的值,僅僅是占位,跟前置++構成重載 Date& operator++(); Date operator++(int); Date& operator--(); Date operator--(int);
?.c內實現(xiàn):
// 前置++ Date& Date::operator++() { *this += 1; return *this; } // 后置++ // 增加這個int參數(shù)不是為了接收具體的值,僅僅是占位,跟前置++構成重載 Date Date::operator++(int) { Date tmp = *this; *this += 1; return tmp; } Date& Date::operator--() { *this -= 1; return *this; } Date Date::operator--(int) { Date tmp = *this; *this -= 1; return tmp; }
五. 減法的重載(日期-日期)
技巧:
- 預設大小:得以計算絕對值
- 預設flag:得以實現(xiàn)最終結果
.c文件實現(xiàn):?
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 n = 0; while (min != max) { ++min; ++n; } return n * flag; }
六.完整代碼實現(xiàn)?
頭文件:文章來源:http://www.zghlxwxcb.cn/news/detail-455796.html
#pragma once #include<iostream> #include<assert.h> using namespace std; class Date { // 友元函數(shù)聲明 friend ostream& operator<<(ostream& out, const Date& d); friend istream& operator>>(istream& in, Date& d); public: Date(int year = 1, int month = 1, int day = 1); void Print() const { cout << _year << "-" << _month << "-" << _day << endl; } Date(const Date& d) // 錯誤寫法:編譯報錯,會引發(fā)無窮遞歸 { _year = d._year; _month = d._month; _day = d._day; } bool operator<(const Date& x) const; bool operator==(const Date& x) const; bool operator<=(const Date& x) const; bool operator>(const Date& x) const; bool operator>=(const Date& x) const; bool operator!=(const Date& x) const; int GetMonthDay(int year, int month); // d1 + 100 Date& operator+=(int day); Date operator+(int day) const; Date& operator-=(int day); Date operator-(int day) const; Date& operator++(); Date operator++(int); Date& operator--(); Date operator--(int); int operator-(const Date& d) const; // 流插入不能寫成成員函數(shù)? // 因為Date對象默認占用第一個參數(shù),就是做了左操作數(shù) // 寫出來就一定是下面這樣子,不符合使用習慣 //d1 << cout; // d1.operator<<(cout); //void operator<<(ostream& out); /*int GetYear() { return _year; }*/ private: int _year; int _month; int _day; }; ostream& operator<<(ostream& out, const Date& d); istream& operator>>(istream& in, Date& d);
.c文件:文章來源地址http://www.zghlxwxcb.cn/news/detail-455796.html
#include "Date.h" 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; assert(false); } } bool Date::operator<(const Date& x) const { if (_year < x._year) { return true; } else if (_year == x._year && _month < x._month) { return true; } else if (_year == x._year && _month == x._month && _day < x._day) { return true; } return false; } bool Date::operator==(const Date& x) const { return _year == x._year && _month == x._month && _day == x._day; } // 復用 // d1 <= d2 bool Date::operator<=(const Date& x) const { return *this < x || *this == x; } bool Date::operator>(const Date& x) const { return !(*this <= x); } bool Date::operator>=(const Date & x) const { return !(*this < x); } bool Date::operator!=(const Date& x) const { return !(*this == x); } int Date::GetMonthDay(int year, int month) { static int daysArr[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; //if (((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) && month == 2) if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))) { return 29; } else { return daysArr[month]; } } Date& 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; } // d1 + 100 Date Date::operator+(int day) const { Date tmp(*this); tmp += day; return tmp; /*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) { if (day < 0) { return *this += -day; } _day -= day; while (_day <= 0) { --_month; if (_month == 0) { _month = 12; --_year; } _day += GetMonthDay(_year, _month); } return *this; } Date Date::operator-(int day) const { Date tmp = *this; tmp -= day; return tmp; } // 前置++ Date& Date::operator++() { *this += 1; return *this; } // 后置++ // 增加這個int參數(shù)不是為了接收具體的值,僅僅是占位,跟前置++構成重載 Date Date::operator++(int) { Date tmp = *this; *this += 1; return tmp; } Date& Date::operator--() { *this -= 1; return *this; } Date Date::operator--(int) { Date tmp = *this; *this -= 1; return tmp; } // d1 - d2; 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 n = 0; while (min != max) { ++min; ++n; } return n * flag; } //void Date::operator<<(ostream& out) //{ // out << _year << "年" << _month << "月" << _day << "日" << endl; //} // 21:20繼續(xù) ostream& operator<<(ostream& out, const Date& d) { out << d._year << "年" << d._month << "月" << d._day << "日" << endl; return out; } istream& operator>>(istream& in, Date& d) { int year, month, day; in >> year >> month >> day; if (month > 0 && month < 13 && day > 0 && day <= d.GetMonthDay(year, month)) { d._year = year; d._month = month; d._day = day; } else { cout << "非法日期" << endl; assert(false); } return in; }
到了這里,關于【C++】年月日計算器——操作符重載的應用(含完整代碼,簡潔)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!