重載操作符是具有特殊名稱的函數:保留字operator後接定義的操作符符号。如:
[cpp] view plain copy

- Sales_item operator+(const Sales_item &,const Sales_item &);
除了函數調用操作符之外,重載操作符的形參數目(包括成員函數的隐式this指針)與操作符的操作數數目相同。
重載操作符必須具有一個類類型操作數,重載操作符必須具有至少一個類類型或枚舉類型的操作數。這條規則強制重載操作符不能重新定義用于内置類型對象的操作符的含義。
用于内置類型的操作符,其含義不能改變:
[cpp] view plain copy

- int operator+(int,int); //Error
在 && 和 || 的重載版本中,兩個操作數都要進行求值,而且對操作數的求職順序不做規定。是以,重載 && 、 || 和逗号操作符不是一種好的做法!
作為類成員的重載函數,其形參看起來比操作數數目少1。作為成員函數的操作符有一個隐含的this形參指針,限定為第一個操作數!
一般将算術和關系操作符(“對稱”操作符)定義為非成員函數,而将指派操作符定義為成員:
[cpp] view plain copy

- Sales_item &Sales_item::operator+=(const Sales_item &);
- Sales_item operator+(const Sales_item &,const Sales_item &);
當操作符為成員函數時,this指向左操作數,是以即使複合指派是二進制操作符,成員複合指派操作符也隻接受一個(顯式的)形參。使用操作符時,一個指向左操作數的指針自動綁定到this,而右操作符限定為函數的唯一形參。
操作符重載和友元關系
操作符定義為非成員函數時,通常必須将它們設定為所操作類的友元,因為操作符通常需要通路類的私有部分!
[cpp] view plain copy

- class Sales_item
- {
- friend std::istream &operator>>(std::istream &,Sales_item &);
- friend std::ostream &operator<<(std::ostream &,const Sales_item &);
- public:
- Sales_item &operator+=(const Sales_item &);
- };
- //不需要将加操作符設定為友元,它可以用public成員operator+=實作
- Sales_item operator+(const Sales_item &,const Sales_item &);
使用重載操作符
使用重載操作符的方式,與内置類型操作數上的使用操作符的方式一樣。
1)假定item1和 item2是 Sales_item對象,可以列印它們的和,就像列印兩個int的和一樣:
[cpp] view plain copy

- cout << item1 + item2 << endl;
2)也可以像調用普通函數一樣調用重載操作符函數:
[cpp] view plain copy

- cout << operator+(item1,item2) << endl;
調用成員操作符函數與調用任意其他函數是一樣的:指定運作函數的對象,然後使用點或箭頭操作符擷取希望調用的函數,同時傳遞所需數目和類型的實參。
[cpp] view plain copy

- item1 += item2
- item1.operator+=(item2);
重載操作符的設計:
1、不要重載具有内置含義的操作符
指派操作符、取值操作符和逗号操作符對類類型操作數有預設含義。如果沒有特定重載版本,編譯器就定義一下這些操作符:
1)合成指派操作符進行逐個成員指派:使用成員自己的指派操作符依次對每個成員進行指派。
2)預設情況下,取位址操作符和逗号操作符在類類型對象上的執行,與在内置類型對象上的執行一樣。取位址操作符傳回對象的記憶體位址,逗号操作符從左至右計算每個表達式的值,并傳回最右邊操作數的值。
3)内置邏輯與(&&)與邏輯或(||)操作符使用短路求值。如果重新定義該操作符,将失去操作符的短路求值特性!
【最佳實踐】
重載逗号、取位址、邏輯與、邏輯或等操作符通常不是好做法!這些操作符都具有擁有的内置含義,如果我們定義了自己的版本,就不能再使用這些内置含義!
有時我們需要定義自己的指派運算。這樣做時,它應表現得類似于合成操作符:指派之後,左右操作數的值應是相同的,并且操作符應傳回對左操作數的引用。重載的指派運算應在指派的内置含義基礎上進行定制,而不是完全繞開。
2、大多數操作符對類對象沒有意義
除非提供了重載定義,指派、取位址和逗号操作符對于類類型操作數沒有意義。
為類設計操作符,最好的方式是首先設計類的公共接口。定義了接口之後,就可以隻考慮應将哪些操作符定義為重載操作符。那些邏輯上可以映射到某個操作符的操作可以考慮作為候選的重載操作符。如:
1)相等測試操作應使用operator=
2)一般通過重載移位操作符進行輸入和輸出
3)測試對象是否為空的操作可用邏輯非操作符operator!表示。
3、複合指派操作符
如果一個類有算術操作符或位操作符,那麼,提供相應的複合指派操作符一般是個好主意!
4、相等和關系操作符
将要用作關聯容器鍵類型的類應定義<操作符,因為關聯容器預設使用鍵類型的 <操作符。即使該類型将隻存儲在順序容器中,類通常也應該定義相等(==)和小于(<)操作符,理由是許多算法假定這個操作符存在。例如sort算法使用 <操作符,而find算法使用 ==操作符。
如果類定義了相等操作符,它也應該定義不等操作符!=。類使用者會假設如果可以進行相等比較,則也可以進行不等比較。同樣的規則也應用于其他關系操作符。如果類定義了<,則它可能應該定義全部的四個關系操作符(>,>=,<,<=)。
5、選擇成員或非成員實作
1)指派=、下标[]、調用()和成員通路箭頭->等操作必須定義為成員,将這些操作符定義為非成員時會發生編譯錯誤。
2)像指派一樣,複合指派操作符通常應該定義為類的成員。但是如果不這麼做,也不會發生編譯錯誤。
3)改變對象狀态或與給定類型緊密聯系的其他一些操作符,如自增、自減和解引用,通常定義為類成員。
4)對稱的操作符,如算術操作符、相等操作符、關系操作符和位操作符,最好定位普通非成員函數。
當内置操作符和類型上的操作存在邏輯對應關系時,操作符重載最有用!