|
//原文鏈接: http://blog.csdn.net/xiegenwendada/article/details/8477209 #include<stdio.h> #include <stdlib.h> /*///////////////////////////// 操作符重載 //////////////////////////////////////////// - - 操作符重載必須是,參數類型或個數不同,還有是否為const,但不以返回值的類型左判斷。 - - ------------------------------------------------------------------------------------ - | 不能重載的操作符號 | 可以重載的操作符 | - ------------------------------------------------------------------------------------ - | . .* :: ?: new delete sizeof | new new[] delete delete[] + - * / % ^ | - | typeid static_cast dynamic_cast | & | ~ ! = < > += -= *= /= %= ^= &= |= | - | const_cast reintERPret_cast | << >> >>= <<= == != <= >= && || ++ -- | - | | ->* -> () [] | - ------------------------------------------------------------------------------------- - - - ------------------------------------------------------------------------------------ - | 類成員操作符重載 | 友員函數操作符重載 | - ------------------------------------------------------------------------------------ - | 左右操作數都是該類對象 | 左操作數為其它類型 | - | 必須為類成員操作符: | | - | 賦值(=),下標([]),調用(()) | | - | 和成員訪問箭頭(->) | | - ------------------------------------------------------------------------------------- - //////////////////////////////// 操作符重載 ////////////////////////////////////////////*/// 簡單的重載 class CBaseOperator { public: int nData; //測試的變量 public: CBaseOperator( int nData = 0):nData(nData) { nData++; --nData; } CBaseOperator( const CBaseOperator& cBO) { nData = cBO.nData; } //重載=操作符,一般=操作符和拷貝構造函數是成對出現的。 const CBaseOperator& operator=( const CBaseOperator& cBO) { nData = cBO.nData; return * this; } public: //重載+操作符,簡單的二元操作符重載是最常見也是比較簡單的。基本思路都是這樣,注意如果 //操作符出現在左邊,則只能用友員了。這里了有幾個返回類型是CBaseOperator,return //語句中卻是兩個int相加,這種情況是可以通過的,編譯器會自動構建一個相應的對象返回, //前提是你的構造函數要有相應的參數,這里是int作為參數 int operator+( int nAdd) const { return nData + nAdd; } int operator+( int nAdd) { return nData + nAdd; } friend int operator+( int nAdd, const CBaseOperator& cAdd) { return nAdd + cAdd.nData; } CBaseOperator operator+( const CBaseOperator& cAdd) const { return nData + cAdd.nData; } //重載減法什么的也是一樣。就不寫了。哈哈
//比較操作符重載==,!=,>, >=, <, <=總結:這里都是配套的操作一般來說如果寫一個 //都會重載其他幾個,特別是==,!=。當然也有例外。哈哈。。 bool operator==( const CBaseOperator& cEqual) const { return nData == cEqual.nData; } bool operator == ( int nEqual) const { return nData == nEqual; } friend bool operator ==( int nEqual, const CBaseOperator& cEqual) { return cEqual.nData == nEqual; } bool operator!=( const CBaseOperator& cEqual) const { return nData != cEqual.nData; } //其他的也就不寫了,基本一樣。哈哈
//重載++,--操作符,因為++,--有兩種方式,一種是前增量(++XXX先改變自己,返回), //一種是后增量(改變自己,返回改變前的狀態) //因為重載是判斷參數的,為了能區別前增量和后增量,C++的設計者做了這樣的考慮。 //就是重載后增量的時候在參數列表中加一個int類型參數,這樣就避免的重載的重復了。 //在調用上,如果都重載,那么用int參數的是后增量++,沒有參數的是前增量++, //(注:我在這里說的是成員函數,當然友員的重載參數個數要多一個,以后的我可別說我無知啊。) //如果都重載,那么前增量和后增量都會調用相應的函數,如果只重載了后增量,那么前增量會失敗 //如果只重載了前增量,就會無論是前增量和后增量都會調用這個函數。所以一般他們也是成對 //出現的,除非你懶,只寫前增量,可惜如果人家要調用后增量呢?結果會錯的哦。哈哈。
//重載后增量.
CBaseOperator operator++( int) { CBaseOperator cTemp = * this; ++nData; return cTemp; } //重載前增量
CBaseOperator& operator++() { ++nData; return * this; } //重載--操作符是一樣的,也不寫了。
//重載[],()等操作符號,同樣[]的參數個數是確定的。 //我之說以把他們寫一起,是因為我錯誤的以為[]的參數個數是可以自己定義。錯了錯了。 //知錯能改是好的,對了,()的參數個數是可以自己定義的。這個就給我們很大的發揮空間了。 //都忘了[],() = 等操作符必須是成員函數,上面有寫。不能用友員和靜態成員函數
//重載[] int operator[]( int nIndex) const { return nIndex; } //重載() int operator()( int a) const { return a; } bool operator()( int a, int b) const { return a > b; } CBaseOperator operator()( int a, int b, int c) { return CBaseOperator(a+b+c+* this); } //重載*,->的操作符,*操作符就是相當于指針的*p;不過這里已經失去了原來的意義,他不是一個指針了。 //但如果是想通過他來得到一些東西,也是可以的,特別在迭代器中常用這種方法。->也是和*配對出現的。 //不過->操作符比較有意思,貌似和(*p).dddd真的差不多,所以返回的應該是一個結構的指針,我們這里 //就返回了本身,當然可以返回任何結構的指針的。(并不是只能返回本身)。
//重載*,這里參數個數是固定的,多寫一個就成了乘法的操作了。哈哈 int operator*() const { return nData; } //重載->
CBaseOperator* operator->() { return this; } //其他的例如&& || 這樣的操作符還是不重載的好。利用其原有的本性
//重載new delete,這里編譯器做了一個限制,new必須返回void*類型, delete必須 //返回void類型。(上面說過函數重載是不檢查返回類型的,和這里并沒有沖突,他只是限定了返回 //類型,而不是只有返回類型不同的函數能重載,這個是編譯器做的工作,一定上確保new能更好的工作吧) //還有就是他們的參數個數都是可以自定義的。new 和 new[] 是兩個不同的操作符,所以還是要分別重載一下。 //delete 和 delete[] 也是兩個不同的操作符。這里只重載了一個。 void* operator new(size_t size) { return malloc(size); } void* operator new[](size_t size) { return malloc(size); } void operator delete( void* P, unsigned int size) { size = 0; free(P); } }; int test_OverLoad() { const CBaseOperator cCo1(100); //判斷+重載符 int nSum = cCo1 + 50; printf("%d\n", nSum); nSum = 50 + cCo1; printf("%d\n", nSum); //這里順便檢測一下拷貝構造函數
CBaseOperator co2(20); CBaseOperator co3 = co2 + cCo1; nSum = co3.nData; printf("%d\n", nSum); nSum = co3 + 60; printf("%d\n", nSum); //檢測+,和=操作符
co3 = 10 + cCo1 + co2 + 20; nSum = co3.nData; printf("%d\n", nSum); //查看比較操作符 if (cCo1 == cCo1 && cCo1 == 100 && 100 == cCo1) { printf("True\n"); } co3 = co2; if (!(co3 != co2)) { printf("True\n"); } //增量操作符,cCo1是不能做這個操作的,因為他是常量
nSum = co2.nData; printf("%d\n", nSum); nSum = (co2++).nData; printf("%d\n", nSum); nSum = (++co2).nData; printf("%d\n", nSum); //測試[],
nSum = cCo1[45]; printf("%d\n", nSum); //測試()
nSum = cCo1(50); printf("%d\n", nSum); if (cCo1(45, 23)) { printf("True\n"); } co2 = co3(10,20,30); nSum = co2.nData; printf("%d\n", nSum); //測試*,這里co2并不是指針哦。只是重載了*的操作符
nSum = *co2; printf("%d\n", nSum); //測試->,這里也一樣。
nSum = co2->nData; printf("%d\n", nSum); //測試new new[] delete, //這里沒有測試輸出。單步就知道了。
CBaseOperator* pCb1 = new CBaseOperator(); CBaseOperator* pCb2 = new CBaseOperator[10]; delete pCb1; delete pCb2; system("pause"); return 0; }
|