1. 程式人生 > >C++運算子過載與型別轉換

C++運算子過載與型別轉換

1.基本概念

    當運算子被用於類型別物件時,C++語言允許我們為其指定新的含義,同時,我們也可以自定義類型別之間的轉換規則。

    以下是運算子過載時需要注意的幾個原則:

  • 當運算子作用於內建型別物件時,我們無法改變該運算子的含義
  • 我們只能過載已存在的運算子,不能發明新的運算子
  • 過載的運算子的優先順序和結合律與對應的內建運算子保持一致
  • 以下運算子不能被過載:  
::    .*    .    ? :
  • 應使用與內建型別一致的含義

    關於選擇過載運算子函式作為成員還是非成員函式:

  • 賦值(=)、下標( [ ] )、呼叫( ( ) )和成員訪問箭頭( -> )必須是成員
  • 複合賦值運算子(+=之類)一般來說應該是成員
  • 改變物件狀態的運算子或者與給定型別密切相關的運算子,入遞增、遞減和解引用運算子,通常應該是成員
  • 具有對稱性的運算子可能轉換任意一端的運算物件,例如算術、相等性、關係和位運算子等,通常應是非成員函式

下面以String為例演示過載各個運算子的用法。

2.輸入和輸出運算子

//輸入輸出函式只能是非成員函式,故要在類內宣告為友元函式
friend std::ostream &operator<<(std::ostream &os, const String &s);
friend std::istream &operator>>(std::istream &is, String &s); 
/*輸出函式較為簡單,需要注意的是,第一個形參要設定為非常量,
因為向流中寫入會改變流的狀態。返回值是形參中的ostream物件,
原因是要實現連續輸出。*/
std::ostream &operator<<(std::ostream &os, const String &s){
    os << s._pstr;
    return os;
}   
    
/*輸入函式較為複雜,因為輸入時無法確定輸入的字串長度,
所以此處使用了vector儲存為字元陣列,再根據字元陣列的長度
開闢堆空間儲存字串*/
std::istream &operator>>(std::istream &is, String &s){
    /*由於輸入長度未知,故需要用vector儲存*/
    delete [] s._pstr;
    std::vector<char> newString;
    char ch;
    while( (ch = is.get()) != '\n' ){
        newString.push_back(ch);    
    }
    /*執行輸入運算子時可能會發生錯誤,故需要檢查是否輸入正確,
若不正確,則vector中沒有資料,不能將vector中的資料複製到string中*/
    if(is)
        strcpy(s._pstr, &newString[0]);
    /*若發生錯誤前對string物件的內容有改動,則需要將物件置為合法狀態
,具體見《C++ Primer》14.2.2節。
    else
        s = String();
    */    
    return is;
} 

3.算術和關係運算符

&nb