二級C++考點歸納:運算符重載

8.1 運算符函數據與運算符重載

二級C++考點歸納:運算符重載

運算符重載是計算機語言固有多態性的體現,是構成計算機語言的基礎之一。

C++把重載的運算符視爲特殊的函數,稱爲運算符函數。運算符重載就是函數重載的一種特殊情況。像對待一般重載函數一樣,編譯系統能夠依據使用運算符的不同環境,即參數(操作數)的數量或類型的差異,區分同一運算符的不同含義。

“運算符重載”是針對C++中原有運算符進行的,不可能通過重載創造出新的運算符。除了。、。*、->*、::、?:這五個運算符外,其他運算符都可以重載。由於很多符號是一元運算符和二元運算符公用的,爲了避免含混,不得爲重載的運算符函數設置默認值,調用時也就不得省略實參。

除了new和delete這兩個較爲特殊運算符以外,任何運算符如果作爲成員函數重載時不得重載爲靜態函數。=、[ ]、()、->以及所有的類型轉換運算符只能作爲成員函數重載,而且不能是針對枚舉類型操作數的重載。

運算符函數的函數名是由運算符前加關鍵字operator構成的,在聲明運算符或調用運算符時都可以用這個名稱。

8.2 典範運算符的重載

1.?關於分數類fraction

fraction的聲明和定義包含在頭文件fraction.h和程序文件中。

一個標準的用fraction表示的分數須滿足以下複印件:

①分母永遠爲正,分數和符號用分子表示;

②分子分母互質,即總表示爲最簡分數。

fraction通過兩個私有數據成員num和den分別保存分子和分母,並在必要時調用standardize函數進行標準化處理,以使num和den的值滿足標準分數的條件。gcd是求兩個整數的最大公約數的函數,standardize在化簡分數時要調用它。

2.?重載取負運算符“-”

因爲fraction用分子的符號代表整個分數的符號,因此所謂“取負”只需對分子num取負就可以了。由於取負運算符“-”是一元運算符,當作爲成員函數重載時參數表中沒有參數,那個唯一的操作數以this指針的形式隱藏在參數表中。爲此,只需要在fraction.h的類聲明中增加:

fraction poerator -()const { return fraction(-num,den);}

就可以了。由於在類聲明中直接給出了完整定義,因此是一個inline函數。

“-”是一個典型的一元運算符,除++、--外的其他一元運算符的重載都可以參考這裏描述的方法。

3.?重載加法運算符“+”

“ +”是一個二元運算符,因此作爲成員函數重載時參數表中只有一個參數,對應於第二操作數,而第一操作數就是對象本身,僅以this指針的形式隱藏在參靈敏表中。

“+”是一個典型的二元運算符,除賦值類運算符外的其他二元運算符的重載都可以參考這裏描述的方法。

4.?重載增1運算符“+ +”

+ +既可以是前綴運算符(前增1),又可以是後綴運算符(後增1)。爲了區分這兩種情況,重載這兩個運算符時必須在格式上有所區別:重載後綴+ +時必須多一個虛擬參數:int,因此從形式上看像是一個二元運算符重載。

5.?重載類型轉換符“long”

類型轉換符必須作爲成員函數重載。在重載類型轉換符時,由於運算符本身已經表示出返回值類型,因此不需要返回值類型的聲明。一個分數可以看成是由一個整數部分和一個純分數部分組成的,爲了取得一個分數的整數部分,可爲fraction重載類型轉換符long.爲此可在fraction.h的類聲明中增加:

opertator long()const { return num/den;}

6.?重載賦值運算符“=”

賦值運算符只能作爲成員函數重載。

常見的真正需要重載賦值運算符的'情況是:類中包含指向動態空間的指針

賦值運算符=的重載應注意以下幾點:

①返回值聲明爲引用,而函數體中總是用語句return *this;返回;

②如果參數被聲明爲指向同類對象的引用或指針,應判別所指向對象的是否與被賦值對象爲同一對象,如果是,立即返回,不做任何賦值處理;

③如果被賦值對象佔用了動態空間或其他資源,應首先釋放這些資源,以便接收新的資源;

④如果參數被聲明爲指針或引用,通常應加上const修飾;

⑤如果參數被聲明爲指針,應判別是否爲空,以便做出特殊處理;

⑥一個類如果需要重載運算符=,通常也就需要定義自己特有的拷貝構造函數,反之亦然。

7.?重載複合賦值運算符“+=”

重載複合賦值類運算符,如+=、-=等,也應遵循上述重載賦值運算符的注意事項。

與賦值運算符不同的是,複合賦值類運算符既可作爲成員函數重載也可作爲非成員函數重載。在後一種情況下,兩個操作數都必須出現在參數表中;爲了保持運算符原有的特性,第一參數應當聲明爲引用(否則就無法改變它的值),返回值也應當像重載“=”那樣聲明爲引用,並在最後將獲得新值的第一參數返回。

8.?重載關係操作符“>”

重載的關係操作符函數應返回邏輯值。對於 fraction的兩個對象,可以通過比較通分後的兩個分子來確定它們的大小。爲此,可在fraction.h的類聲明中增加如下的成員函數聲明:

bool operator>(fraction f){ return num*>*den;}

其他關係運算符可以參照重載。

9?重載下標訪問運算符“[ ]”

運算符[ ]只能作爲成員函數重載。

10?重載C+ +流運算符“??”和“??”

C+ +流的輸入運算符??和輸出運算符??只能作爲非類成員函數重載。在一個類中,如有必要,可將??或??聲明爲友元函數。

8.3 運算符重載應注意的幾個問題

1.?重載的運算符應保持其原有的基本語義

重載的運算符應該體現爲原運算符的功能在新的數據類型上的延伸,它的使用應當使程序中算法的表達顯得更流暢、自然,使閱讀程序的人在不借助於其他說明資料的情況下就能夠正確理解。不要讓重載的運算符去勉強承擔那些更適於一般函數承擔的功能。