天天看點

基本概念

重載的運算符是具有特殊名字的函數:它們的名字由關鍵字 <code>operator</code> 和其後要定義的運算符号共同組成,和其他函數一樣,重載的運算符也包含傳回類型、參數清單以及函數體。

重載運算符函數的參數數量與該運算符作用的運算對象一樣多。如果一個運算符函數是成員函數,則它的第一個運算對象綁定到隐式的 <code>this</code> 指針上,是以,成員運算符函數的顯式參數數量要比運算符的運算對象總數少一個。

對于一個運算符函數來說,它或者是類的成員,或者至少含有一個類類型的參數:

隻能重載已有的運算符,不能發明新的運算符。

<code>+,-,*,&amp;</code> 既是一進制運算符也是二進制運算符,所有這些運算符都可以被重載,從參數的數量可以推斷出到底定義的是那種運算符。

對于一個重載的運算符來說,其優先級和結合律與對應的内置運算符保持一緻。

基本概念

直接調用一個重載的運算符函數

間接調用重載的運算符和直接調用重載的運算符:

這兩次調用是等價的,它們都調用了非成員函數 <code>operator+</code>。

間接和直接調用成員函數:

某些運算符不應該被重載

通常情況下,不應該重載逗号,取位址,邏輯與,邏輯或運算符。

重載之後,邏輯與,邏輯或,逗号運算符的求值順序規則無法保留下來。除此之外,邏輯與和邏輯或運算符的重載版本也無法保留内置運算符的短路求值屬性,兩個運算對象總是會被求值。

C++語言已經定義了取位址運算符和逗号運算符用于類類型對象時的特殊含義,因為這兩個運算符已經有了内置的含義,是以一般不應該重載它們,否則它們的行為将異于常态。

使用與内置類型一緻的含義

如果類執行 <code>IO</code> 操作,則定義移位運算符使其與内置類型的 <code>IO</code> 保持一緻。

如果類的某個操作是檢查相等性,則定義 <code>operator==</code>;如果類有了 <code>operator==</code> 那麼意味着也應該有<code>operator!=</code>。

如果類包含一個内在的單序比較操作,則定義 <code>operator&lt;</code>;如果類有了<code>operator&lt;</code>,則它也應該還有其它關系操作。

重載運算符的傳回類型通常情況下應該與内置版本的傳回類型相容:邏輯運算符合關系運算符應該傳回 <code>bool</code>,算術運算符應該傳回一個類類型的值,指派運算符和複合指派運算符應該傳回左側運算對象的一個引用。

選擇作為成員或非成員

指派<code>=</code>、下标<code>[]</code>、調用<code>()</code>、和成員箭頭<code>-&gt;</code>運算符必須是成員。

複合指派運算符一般來說應該是成員,但并非必須,這一點與指派運算符略有不同。

改變對象狀态的運算符或者與給定類型密切相關的運算符,如遞增、遞減和解引用運算符通常應該是成員。

具有對稱性的運算符可能轉換任意一端的運算對象,例如算術,相等性,關系和位運算符等,是以它們通常應該定義成普通的非成員函數。