過載操作符是個好青年,但是要吐槽的是 ,我們時常為了過載操作符編寫許多重複的**。這是枯燥的,但是也是必須的。你過載的越多,你的類的彈性就越大。但是,你也不能為所欲為。玩遊戲總是遵守相應的規則,寫過載操作符亦是如此 !
以下是要遵守的遊戲規則 :
• 一元操作符可以是不帶引數的成員函式或帶乙個引數的非成員函式。
• 二元操作符可以是帶乙個引數的成員函式或帶兩個引數的非成員函式。
• operator=、operator、operator()、operator->只能定義為成員函式。
• operator->的返回值必須是乙個指標或能使用->的物件。
• 過載 operator++ 和 operator--時帶乙個 int 引數表示字尾,不帶引數表示字首。
• 除 operator new 和 operator delete 外,過載的操作符引數中至少要有乙個非內建資料型別。
• 過載的的操作符應盡量模擬操作符對內建型別的行為。
在看完遊戲規則之後,我們就各個部分的實現和注意點進行肢解 。
⒈ 輸入和輸出操作符的過載
對於》和《的過載要注意以下幾個要點 :
① io操作符必須為 非成員函式,如果將其定義為成員函式,那麼io操作符的操作習慣將和正常的習慣相反。多怪啊!此時,你或許會問,那我怎麼呼叫物件中的私有成員呢?別急,我們不是有友員和友類嗎?將io操作符過載函式定義成類的友員函式,這個問題就迎刃而解了 。
② 在輸入期間,我們可能會碰到錯誤。此時,要恢復物件為初始狀態。也就是,在輸入之前什麼樣子,我們就恢復成那個樣子。
③ 這個要點是摘至《c++ primer》,我覺得挺好的。我們可以過載操作符,意味著我們自由的空間就大了。但是,我們不要忘了io操作符的本質,不要過度的格式化,應將格式化降到最低。
在注意了幾個要點之後,我們看乙個完整的io操作符的實現例子:
#include
#include
using namespace std;
class myclass ;
myclass(string n, int a, int p, int nm):name(n), id(a), prefix(p), value(nm){} // 利用初始化列表來初始化成員物件
friend ostream &operator<<(ostream &stream, myclass o); // 操作符被定義為非成員函式時,要將其定義為所操作類的友員
friend istream &operator>>(istream &stream, myclass &o);
};ostream &operator<<(ostream &stream, myclass o)
istream &operator>>(istream &stream, myclass &o)
int main()
我覺得,許多的事情都是盡在不言中。看了**,你就知道,這個傢伙是這麼用的,這樣用才是規範的。好了接下來介紹算術操作符和關係操作符。
⒉ 算術操作符和關係操作符的過載
一般而言,將算術操作符和關係操作符定義為非成員函式。
① 算術操作符
那就看**怎麼實現吧:
#include
#include
using namespace std;
class point
;point(int x_, int y_):x(x_),y(y_){};
point(const point &p);
~point(){};
friend point operator+(point &p1, point &p2); // 兩個物件相加
friend point operator+(int value, point &p1); // 物件和值的相加
friend ostream &operator<<(ostream &os, point &p1);
private:
int x;
int y;
};point operator+(point &p1, point &p2)
point operator+(int value, point &p1)
ostream &operator<<(ostream &os, point &p1)
int main()
② 相等操作符
www.2cto.com
首先,「==」相等操作符的兩個物件包含相同的資料,這樣才有比較性。其次,定義了operator==,同時也要定義operator!=。
friend bool operator==(point &p1, point &p2);
friend bool operator!=(point &p1, point &p2);
.......
bool operator==(point &p1, point &p2)
bool operator!=(point &p1, point &p2)
⒊ 賦值操作符
賦值操作符有個強調點,那是賦值必須返回對 *this的引用。要定義為成員函式。
point &operator=(const point &p1);
point &operator+=(const point &p1);
.....
point &point::operator=(const point &p1)
point &point::operator+=(const point &p1)
⒋ 下標操作符
可以從容器中檢索單個元素的容器類一般會定義下標操作符operator。首先,要注意到, 下標操作符必須定義為成員函式。其次,要定義兩個版本,乙個是非const成員並返回引用。乙個是為const成員並返回引用。
#include
using namespace std;
class point
int &operator(int &i)
const int &operator(const int &i)
};int main()
在sgi stl中,可以看到過載的情形:(夠簡潔的 )
reference operator(size_type __n)
const_reference operator(size_type __n) const
⒌ 成員訪問操作符
c++中支援過載解引用操作符(*)和箭頭操作符(->),其中, 箭頭操作符必須定義為類成員函式,解引用則兩者皆可。看看以下的用法:
_reference operator*() const
pointer operator->() const // 返回指標
⒍ 自增和自減操作
a++,++a,--b,b--。是不是有點煩人?但是看了過載的意義之後,你就知道,這個東西是不煩人的。也知道了在for迴圈中為什麼要強調用++a了。
在c++中,並沒有特別要求說一定要為成員函式,但是為成員函式是乙個不錯的選擇 。
還有要注意的是 :
① 為了與內建型別一致,字首式操作符應返回被增量或減量物件的引用;
② 字尾式返回舊值,應作為值返回,不是返回引用,所以返回不用引用。
現在看看如何使用:
point &operator++(); // 為了與內建型別一致,字首式操作符應返回被增量或減量物件的引用
point operator++(int); // 返回舊值,應作為值返回,不是返回引用
point &operator--();
point operator--(int);
....
// 前增
point &point::operator++()
// 後增
point point::operator++(int)
// 前減
point &point::operator--()
// 後減
point point::operator--(int)
知道為什麼說要強調說字首式了嗎 ?看看字首和字尾的區別,你就知道那個效率會高。。。
總結,這些東西寫的有點辛苦,寫寫停停的。請大牛指正其中不妥之處,小菜謝謝了。。。
操作符過載
ifndef vertex h define vertex h class vertex vertex float px float py float pz vertex operator const vertex p vertex operator const vertex p void oper...
操作符過載
1.操作符是靜態方法,返回值表示操作結果,引數是運算元。2.操作符過載需要在過載的操作符前加上operator關鍵字。3.最好少用操作符過載,只有在意義明晰而且與內建類的操作一致時才適合使用,以免造成混亂。以建立的分數類 fraction 中的 為例,該分數類中有兩個int型的私有屬性 分子 num...
過載操作符
1.過載操作符1.1 限制過載操作符具有以下限制 1 只有c 預定義的操作符集中的操作符才可以被過載 2 對於內建型別的操作符,它的預定義不能被改變,應不能為內建型別過載操作符,如,不能改變int型的操作符 的含義 3 也不能為內建的資料型別定義其它的操作符 4 只能過載類型別或列舉型別的操作符 5...