實現string類的幾種方式

2021-07-30 07:08:10 字數 4224 閱讀 5248

淺拷貝

淺拷貝的意思就是在拷貝建構函式、賦值運算子函式時並沒有給新物件開闢一塊空間,而是直接二者公用一塊空間。這個問題就很麻煩了。

s1,s2共用一塊空間,此時不論s1怎樣修改,都會影響到s2,而且析構s1後,s2就無法繼續使用。

簡單**實現如下:

class

string

string(string& s)

~string()

}string operator=(const

string& s)

private:

char* _pstr;

};int main()

那麼最終析構s2後,s1無法正常析構。若給s1賦乙個新的字串,那麼s2也隨之改變。

所以,淺拷貝是乙個失敗的演算法。

2. 深拷貝

深拷貝就是在拷貝的同時,給新物件開闢乙個與原物件完全相同的空間以儲存資料。這個時候每個物件都使用各自獨有的一塊空間,各自互不影響。

簡單**實現如下:

class string

string(const string& s)

:_pstr(new

char[strlen(s._pstr) + 1])

~string()

}string& operator=(const string& s)

return *this;

}char& operator(const

int idx)

const

char& operator(const

int idx)const

size_t size()const

return count;

}size_t lengh()const

return count;

}///

//////

//////

//////

//////

//////

//////

///////

bool

operator>(const string& s)

else

if ((*ptemp) == (*ptemp))

else

return

false;

}return

false;

}bool

operator

<(const string& s)

else

if ((*ptemp) == (*ptemp))

else

return

false;

}return

false;

}bool

operator==(const string& s)

else

return

false;

}return

true;

}bool

operator!=(const string& s)

else

return

true;

}///

//////

//////

//////

//////

//////

//////

/////

void copy(string& s)

}bool strstr(const string& s)

}pcur++;

}return

false;

}string& operator+=(const string& s)

_pstr = tmp;

while (*p)

*_pstr = '\0';

return *this;

}friend ostream& operator

<<(iostream& os, string& s);

private:

char* _pstr;

};ostream& operator

<<(iostream& os, string& s)

int main()

這樣操作的好處就是每乙個物件擁有自己獨有的空間,各自處理自己的資料,也是一般大眾化的實現方法。

4. 深拷貝的現代化寫法:

和普通的深拷貝的實現原理一樣,但是寫法更簡單。看**:

class

string

string(const

string& s)

~string()

string& operator=(const

string& s)

string& operator=(char* pstr)

private:

char* _pstr;

};int main()

此時對s1賦值時,s3並沒有發生變化,且s1,s2,s3的位址也不相同。這個寫法主要是先使用建構函式使用被賦值的物件的字串構造出乙個臨時物件,然後讓臨時物件與當前物件的字串交換,使用址傳遞,所以現在當前物件的字串已經達到預期效果,相當於被構造出來了。

4. 帶有引用計數的拷貝

這個的實現方式是在類中開闢乙個儲存字串的char型別的指標時,使用開闢乙個int整型的指標,這個int指標裡面儲存的是當前有幾個物件共同指向這塊字串的空間。在使用拷貝建構函式、賦值運算子過載的函式時,直接使二者共同指向一塊空間。

析構時,如果這個物件的引用計數空間的計數減一後為0才允許析構。

但當需要單獨對某乙個物件作出操作時,就需要用到深拷貝裡面的方法,對新物件重新開闢一塊空間,再繼續操作。

這種方法在不需要單獨對某乙個物件做特殊操作時,是乙個很好的方法。

簡單的**實現:

class string

}string(const string& s)

: _pstr(s._pstr)

, _pcount(s._pcount)

~string()

}string& operator=(const string& s)

_pstr = s._pstr;

_pcount = s._pcount;

(*(_pcount))++;

}return *this;

}string& operator=(char* pstr)

_pstr = new

char[strlen(pstr) + 1];

strcpy(_pstr, pstr);

_pcount = new

int(1);

return *this;

}friend ostream& operator

<<(ostream& os, string& s);

private:

char* _pstr;

int* _pcount;

};ostream& operator

<<(ostream& os, string& s)

void funtest()

int main()

這裡推薦乙個部落格大家可以去看看,寫的特別詳細,而且沒有錯誤:

4.寫時拷貝

其實寫時拷貝和引用計數都可以算是寫時拷貝,都是在更改物件時再對其開闢空間,平時只是簡單的使用的時候,大家都指向同一塊空間。但這個「寫時拷貝」我指的時在類中只開闢一塊空間,儲存計數的空間放在儲存字串的空間的前面的4個位元組。這就需要開闢空間的時候多開闢4個位元組(加』\0』就是多5個了).其他的方法同維護引用計數的方法。

來看**:

class string

string(const string& s)

:_pstr(s._pstr)

~string()

}string& operator=(string& s)

int& getrefcount(char* tmp)

void release()

}private:

char* _pstr;

};int main()

是不是有異曲同工之妙呢?

這兩種寫時拷貝(寫時開闢空間)的方法適合於大型工程中,這樣做的目的就是減少開銷和達到空間的合理使用。

文中如有問題,請提出,我會第一時間改正。

string類的實現

參考c primer.string類的實現,清翔兔 06,jan.includeusing namespace std class string string void private char m data inline string string const char str inline st...

String類的實現

學習資料結構寫了乙個string的類,貼出來求指教 ifndef string h h define string h h include include include define defaultsize 128 class string maxsize為傳入引數的string string c...

string類的實現

include using namespace std class string public string const char str 0 普通建構函式 string const string other 拷貝建構函式 string void 析構函式 string operator const...