自己動手寫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'; //
}
};
接下來可以開始運算子過載了。。。
編譯器沒有對陣列越界的問題進行善意的提醒,所以我們可以自己來給自己進行安全的檢驗。所以選擇了過載[ ]。
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;
}
未完待續。。。。。