1. 程式人生 > >自己動手寫string類(一)

自己動手寫string類(一)

         前面說到了string類,為什麼她就能夠那麼方便呢? 其實這是有原因的,因為它的背後有很多願意默默奉獻的英雄們在大力支援~~~今天就讓我們來初窺其神祕的面紗(其實也只是冰山一角)! !

         我們都知道string物件可以直接進行輸入,輸出,賦值,相加,比較等等,其實說到底就是string類中對大量的運算子進行了過載。那什麼是運算子過載呢? 這個是C++重要的一部分內容,今天就一起來探討探討!!

        我對運算子過載的理解簡單說是這樣的,對已有的運算子重新定義,使得滿足我們使用的要求。(具體的請參考C++有關教材)。下面我們就直接自己動手寫string類了。。。。

        常見的建立物件的方法有String str; 或者 String str("i love C++"); 建立物件時就必須呼叫建構函式,所以這裡可以通過預設建構函式來構造一個空字串,同時也應該有一個帶引數的建構函式。-----這裡為了區別string類,就用String作為類名。

         class String{

                    char *str ;    //指向字串的指標
                     int len;        //記錄字串的長度

        public:
                    String(){         //建立無參物件時呼叫
                         len = 0;                        
                         str = new char[1];        //動態申請一個char大小的記憶體空間
                         str[0] = '\0';                  //表示字串為空
                   }


                   String(const char* const str){         //建立帶引數的物件時呼叫
                          len = strlen(str);                      //取得字串的長度
                          this->str = new char[len+1];   //動態申請長度+1大小的記憶體空間,並把char陣列的記憶體地址賦給str

                          for(int i=0; i<len; i++)             //用傳過來的字串初始化
                                  this->str[i] = str[i];          //這裡會對陣列越界進行檢驗(見下面)
                         this->str[len] = '\0';                 //

因為是陣列,'\0'為結束標誌

                   }

       };

       接下來可以開始運算子過載了。。。

       編譯器沒有對陣列越界的問題進行善意的提醒,所以我們可以自己來給自己進行安全的檢驗。所以選擇了過載[ ]。

        char& operator[](unsigned int len)        //len作為陣列的下標
       {
                 if(len > this->len)
                       return str[this->len-1];         //如果下標超過了陣列長度,那麼返回陣列最後一個可見字元
                else
                       return str[len];                    //否則返回該下標的陣列元素
       }

       同時可以對這個函式進行過載,對const物件也可以進行操作

       char  operator[](unsigned int len) const        //len作為陣列的下標
       {
                 if(len > this->len)
                       return str[this->len-1];         //如果下標超過了陣列長度,那麼返回陣列最後一個可見字元
                else
                       return str[len];                    //否則返回該下標的陣列元素
       }

       輸出<<運算子 和 過載輸入>>

      對於物件可以直接這樣輸出cout<<str; 是因為過載了operator<< 。

       friend ostream& operator<<(ostream& os, const String& s)     // 固定格式 ,引數型別要對應cout是ostream物件
      {
                 os<<s;
                 return os;                              //返回ostream物件,為的是可以進行連續的輸出 如cout<<str1<<str2;
      }  

         過載輸入>> 與上面類似。。。

         friend istream& operator>>(istream& is, String& s)   
       {
                 is>>s;
                 return is;
        }

        為了能夠簡單的對兩個物件進行賦值,如 str1 = str2 ;  必須過載賦值 = 運算子。。。

        String& operator=(const String& s)       
       {
               if(this == &s)               //如果字串相同,返回當前物件
                      return *this;
              delete []str;                 //否則,釋放當前物件記憶體空間
             len = s.getlen();          
             str = new char[len+1];  //重新申請記憶體空間
             for(int i=0; i<len; i++)   //把字串s儲存在str所指向的空間
                     str[i] = s[i];
             str[i] = '\0';

                     return *this;              
       }

       未完待續。。。。。