條款7 千萬不要過載 , 和,操作符

2021-07-25 05:12:39 字數 1491 閱讀 8504

c++對於「真假值表示式」採用所謂的「驟死式」評估方式。意思是一旦該表示式的真假值確定,即使表示式中還有部分尚未檢驗,整個評估工作仍告結束。

如果在global scope或是在每個class內對operator&&和operator||兩函式進行過載工作,那麼「函式呼叫 語義」會取代「驟死式 語義」。

也就是說,下面這個式子:

if(expression1 && expression2) ...
會被編譯器視為以下兩者之一:

if(expression1.operator&&(expression2)) ...

//假設operator&&是個member function

if(operator&&(expression1,expression2)) ...

//假設operator&&是個全域性函式

這將產生重大的區別:

1.當函式呼叫動作被執行,所有引數值都必須評估完成,所以當我們呼叫operator&&和operator||時,兩個引數都已評估完成。換句話說沒有什麼驟死式語義。

2.c++語言規範並未明確定義函式呼叫動作中各引數的評估順序,所以沒辦法知道expression1和expression2哪個會先被評估。

所以,如果你將&&和||過載,就沒有辦法提供程式設計師預期的某種行為模式。所以請不要過載&&或||。

c++同樣也有一些規則來定義逗號操作符(,)面對內建型別的行為。表示式中如果內含逗號,那麼逗號左側會先被評估,然後逗號的右側再被評估;最後,整個逗號表示式的結果以逗號右側的值為代表。

如果把操作符寫成乙個non-member function,你絕對無法保證左側表示式一定比右側表示式更早被評估,因為兩個表示式都被當做函式呼叫時的自變數,傳遞給該操作符函式,而你無法控制乙個函式的自變數評估順序。

而將操作符寫成乙個member function,你仍然不能保證逗號操作符的左運算元會先被評估,因為編譯器並不強迫做這樣的事情。所以不要輕率地將它過載。

你不能過載以下操作符:

.      .*      ::      ?: 

new delete sizeof typeid

static_cast dynamic_cast const_cast reinterpret_cast

你可以過載的操作符有:

operator new operator delete

operator new operator delete

+ - * / % ^ & | ~ ! = < > += -= *= /= %=

^= &= |= << >> >>= == != <= >= && ||

++ – , ->* -> ()

而只因為可以過載這些操作符,就毫無理由地去進行,是沒有道理的。

如果你沒有什麼好理由將某個操作符過載,就不要去做。

為什麼不要過載 , 操作符

是一種邏輯運算子,它內建實現了短路原則,比如 condition1 condition2,如果 condition1 不滿足,那麼 condition2 的值將不會得到計算,同理如果 condition1 condition2,當 condition1 為真時,condition2 的值也不會得到計...

過載前置操作符和後置操作符

i i的值作為返回值,i自增1 i i自增1,i的值作為返回值 現代編譯器產品會對 進行優化 優化使得最終的二進位制程式更加高效 優化後的二進位制程式丟失了c c 的原生語義 不可能從編譯後的二進位制程式還原c 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...