[c/c++ digestion] – 過載操作符
日期: 2010-04-17
[1] 過載操作符
過載操作符從大的方面來講可以分為兩類:最好或必須作為類的成員函式的,以及相反。而具體地講,最好或必須作為類的成員函式的有賦值操作符 ( = ) 、下標操作符 ( ) 、呼叫操作符 ( () ) 、成員訪問箭頭操作符 ( -> ,目前列出的操作符都必須為成員函式 ) 、星號解引用操作符 ( * ) 、復合賦值操作符 ( += 等 ) 、自增、自減。其它的一些操作符,如算術操作符、相等操作符、關係操作符和位操作符,最好定義為非成員函式,在這種情況下,通常需要將其定義為類的友元函式。當然,還有一些是不建議過載的操作符,如逗號、取位址運算子和邏輯運算子等。
[2] 賦值操作符
賦值操作符必須是類的成員函式,因為編譯器需要知道類是否有賦值操作符這個資訊。並且,賦值操作符必須返回對 *this 的引用,也就是左運算元 ( 物件自身 ) 的引用。
同樣的,復合賦值操作符也應返回對 *this 的引用。
如下是一段示例**:
#include using namespace std; class demo demo(int t): val(t){} demo(const demo &demo) ~demo(){} demo& operator=(const demo &demo) demo& operator+=(const demo &demo) void showval() private: int val; }; int main()
通常定義了賦值操作符,那麼接著定義複製建構函式和復合賦值操作符是比較合理的。接著又為了體現複製建構函式的運用,直接在例項化 d1 的時候使用了 demo d1 = 2; 這樣的語句,就類似 string str = 「hello」; 先呼叫對應引數的建構函式建立臨時物件再呼叫複製建構函式。
[3] 下標操作符
下標操作符也必須定義為類的成員函式。並且,下標操作符有個需要注意的問題是,當它出現在賦值操作符的任意一邊時都應該能正常工作,所以下標操作符應該返回引用,這樣才能得到左值,使得下標操作符可以出現在賦值操作符的任意一邊。
可以使用下標操作符還保證不非法越界:
#include using namespace std; class demo demo(int sz): flag(true), size(sz) ~demo() int& operator(const int index) else return p[index]; } } private: bool flag;// 需要有個標誌判斷是否有為 p 非配空間,避免非法訪存 int *p; int size; }; int main()
[4] 箭頭和星號操作符
箭頭操作符必須定義為類成員函式,而星號操作符則無此要求。有了這兩種操作符可以過載,就可以使類表現得像指標一樣,或者也可以稱其為指標型的類,由此可以實現如 smart pointer 這種雖然號稱智慧型指標但也是智慧型得有限的類。而 stl 中的迭代器就是乙個典型的應用:
#include #include using namespace std; int main ()
[5] 算術操作符和關係操作符
算術操作符和關係操作符一般應定義為非成員函式。其中為了保持與內建操作符一致,加法不返回引用。並且,如果可以的話,使用復合賦值操作符來實現算術操作符會更有效率。
相等操作符和不等操作符一般也是相生的,因為需要其一時往往需要另一,並且往往其中乙個操作符是呼叫另乙個操作符實現的。
而當使用的容器運作於某些演算法需要關係操作符時,如小於操作符,定義該種關係操作符往往會使得**更加有效率以及簡潔。
[6] 自增、自減操作符
自增、自減操作符的過載可以使得乙個類表現得如整型一般,從而可以作為迭代器,並且又分為字首和字尾兩種運算。
上一段**(關於星號和箭頭操作符)中就有使用到過載自增操作符。通常這種應用是通過 3 個指標來實現的,乙個是 begin ,乙個是 current ,還有乙個是 end 。當然名稱不一定如此。首先使用 begin 指標確定迭代開始的初始位置,並使用 end 指標限定範圍,最後通過 current 指標遍歷元素。
為了與內建型別一致,或者說為了保持習慣用法,字首式操作符應該返回發生改變(增或減)後的物件的引用,而字尾式操作符應該返回舊值。
另外,為了區分字首式操作符和字尾式操作符,指定了字尾式操作符函式接收乙個無用的 int 型形參,形如 operator++(int) 表示字尾式操作符,而 operator++() 表示字首式操作符。
[7] 輸入輸出操作符
上面提了許多,但想來最常用的過載操作符可能是輸入輸出操作符,並且這二者最好定義為非成員函式,使其符合使用標準。
從標準使用的角度來講,輸出操作符應該接受 ostream& 作為第乙個形參,並返回對該形參的引用:
#include using namespace std; class demo ~demo(){} friend ostream& operator<<(ostream &os, const demo &demo); private: int p; }; ostream& operator<<(ostream &os, const demo &demo) int main()
而輸入操作符也具有相同模式:接受 istream& 引數作為第一形參並返回該形參的引用。此外,輸入操作符還需要注意的是讀入過程的錯誤處理。
[8] 呼叫操作符
最後乙個提及的過載操作符是呼叫操作符,它必需作為成員函式,而且因為作用同函式類似,所以具有呼叫操作符的類經例項化而得的物件也被稱為函式物件( function object )。
#include using namespace std; class demo }; int main()
如上,使用的是 demo 類的呼叫運算子,功能就好像乙個返回較大值的函式。
C C Digestion 過載操作符
c c digestion 過載操作符 日期 2010 04 17 1 過載操作符 過載操作符從大的方面來講可以分為兩類 最好或必須作為類的成員函式的,以及相反。而具體地講,最好或必須作為類的成員函式的有賦值操作符 下標操作符 呼叫操作符 成員訪問箭頭操作符 目前列出的操作符都必須為成員函式 星號解...
適合過載操作
所有的過載操作符,你見過到目前為止讓你定義的操作符的形參的型別,但引數的數目是固定的基於經營者的型別。例如,運算子總是有兩個引數,而不是總是乙個邏輯運算元。括號 是乙個特別有趣的運算元,它可以讓你不同的型別和引數,它需要數!有兩件事情要記住 第一,括號操作符必須為成員函式的實現。第二,在非類c 的,...
操作符過載
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...