時間:2014.03.11
地點:基地二樓
---------------------------------------------------------------------
C++中譬如 && 和 || 等運算符和C一樣,執行短路運算,或驟死式評估方式,即一旦該表達式的真假值確定,即使表達式中還有部分尚未檢驗,整個評估工作已經結束。比如:
char *p; ... if( (p!=0)&&(strlen(p)>10) ...這裡無需擔心調用strlen時p是否為null指針,因為p是否為0這部分檢測如果是否定的,strlen已經不會發生調用,整個表達式真假已經確定,這種驟死式的評估方式對於 && 運算符同樣適用。
---------------------------------------------------------------------
C++允許為用戶定制類型量身定做 && 和 || 操作符,即運算符重載的方式,如果你這麼做,那麼這種驟死式的游戲規則將會打破,重載後相當於是函數調用,不再具備上述語義,程序邏輯會發生改變。函數調用式語義和驟死式語義的區別是:
1.函數調用動作被執行時,所有參數值都必須先評估完成再工作,於是在調用重載後的 && 和 || 時,參數的合法性已經完全確立。
2.C++規范並未標明函數調用中各參數的評估順序,誰先誰後不確定。而驟死式評估法總是由左向右對表達式進行評估。
因此,如果你對 && 和 || 進行重載,就不會再擁有某些預期的功能,所以建議不要重載 && 和 ||
---------------------------------------------------------------------
逗號也是一個操作符,特別是在for循環更新區中最常用。比如將字符串反轉函數:
void reverse(char s[]){ for(int i=0,j=strlen(s)-1;i這裡就用到了逗號操作符,因為for循環的最後一個成分必須是表達式,使用個別語句比如分號形式改變i和j的值是不合法的。且C++規定,表達式如果含逗號,那麼逗號左側會先被評估,右側後評估,最後這個表達式的結果以逗號右側的值為代表。所以上述整個逗號表達式首先評估++i,然後評估--j,而整個逗號表達式的結果是 --j的返回值。 ---------------------------------------------------------------------
四、立場
知道這些運算符是可重載後,重載運算符必須模仿這些行為,但不幸的是你無法執行也無必要執行這樣的模仿。假如重載操作符為普通函數,此時因為兩個表達式都當做函數調用的參數,所以無法保證評估順序。而即便你將操作符重載為成員函數也還是無法保證這種從左到右的驟死式評估方式,於是,不要去重載具有這類特征的運算符。
以下列出不能重載的操作符
. (點號) .* (點號+星號) :: (域運算符) ?:
new delete sizeof typeid
static_cast dynamic_cast const_cast reinterpret_cast (四大cast-四大類型轉換符)
而能重載的操作符有:
operator new operator delete operator new[] operator delete[] //new 和 delete加上operator後都能重載了
各類算術運算符和邏輯運算符和位運算符和比較運算符,簡寫運算符可重載
++ -- , -> ->* () []
記住:重載運算符的目的是讓程序更容易被閱讀、被撰寫、被理解,如果沒有好的理由這麼做不要去做,特別是 && || ,實在沒有什麼好處,所以幾乎別考慮重載。