1、除了函數調用符之外,重載操作符的形參數目(包括成員函數的隐式this指針)與操作符的操作數目相同。函數調用操作符可以接受任意數目的操作數。
表1 可重載的操作符名
+
-
*
/
%
^
&
|
~
!
,
=
<
>
<=
>=
++
--
<<
>>
==
!=
&&
||
+=
-=
/=
%=
^=
&=
|=
*=
<<=
>>=
[]
()
->
->*
new
new[]
delete
delete []
表2 不能重載的操作符
::
.*
.
?:
不能通過連接配接其他合法符号來建立任何新的操作符。
2、重載操作符必須具有一個類類型/枚舉類型操作數。不能改變内置操作符原有的優先級和結合性。除了函數調用操作符operator()之外,重載操作符時使用預設實參是非法的。
3、作為成員函數的操作符有一個隐含的this指針,限定為第一個操作數。
4、一般将算術和關系操作符定義為非成員函數,而将指派操作符定義為成員。
5、加傳回右值,而複合指派傳回對左操作數引用。
6、重載的設計
1)不要重載具有内置含義的操作符
指派操作符(可定義自己的)、取位址操作符和逗号操作符對類類型操作數有預設含義。内置邏輯與(&&)和邏輯或(||)操作符使用短路求值,如果重新定義該操作符,将失去操作符的短路求值特征。
2)用作關聯容器鍵類型的類就有<操作符,順序容器中應定義==操作符。為了相應算法操作的友善。如sort,find等。
3)總結
• 指派(=)、下标([])、調用(())和成員通路箭頭(->)等操作符必須定義為成員,将這些操作符定義為非成員函數将在編譯時标記為錯誤。
• 像指派一樣,複合指派操作符通常應定義為類的成員,與指派不同的是,不一定非得這樣做,如果定義非成員複合指派操作符,不會出現編譯錯誤。
• 改變對象狀态或與給定類型緊密聯系的其他一些操作符,如自增、自減和解引用,通常就定義為類成員。
• 對稱的操作符,如算術操作符、相等操作符、關系操作符和位操作符,最好定義為普通非成員函數。
7、重載操作符的定義示例
1)輸出<<
示例
通常所做格式化應盡量少。
IO操作符必須為非成員函數,否則會出現 item << cout的這種不自然情形。
2)輸入>>
輸入操作符必須處理錯誤和檔案結束的可能性。
通常輸入操作符僅需設定failbit,設定eofbit意思是檔案耗盡,設定badbit指出流被破壞。
3)算術操作符和關系操作符
4)相等操作符與不等操作符一起實作
5)一般而言,指派操作符與複合指派操作符應傳回左操作數的引用(*this)。
6)下标操作符
定義兩個版本:一個為非const成員并傳回引用,另一個為const成員并傳回const引用。
7)成員通路操作符
同樣,也是兩個版本。
重載箭頭操作符必須傳回指向類類型的指針,或傳回定義了自己的箭頭操作符的類類型對象(或引用)。
說明:point->action();
1.If point is a pointer to a class object that has a member named action , then
the compiler writes code to call the action member of that object.
2.Otherwise, if point is an object of a class that defines operator-> , then
point->action is the same as point.operator->()->action . That is, we execute
operator->() on point and then repeat these three steps, using the result of
executing operator-> on point .
3. Otherwise, the code is in error.