詳解C++中String類模擬實現(xiàn)以及深拷貝淺拷貝
在曲沃等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務理念,為客戶提供網(wǎng)站設(shè)計制作、網(wǎng)站制作 網(wǎng)站設(shè)計制作定制開發(fā),公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),網(wǎng)絡(luò)營銷推廣,成都外貿(mào)網(wǎng)站建設(shè)公司,曲沃網(wǎng)站建設(shè)費用合理。
在C語言中/C++中,字符串是一個應用很廣泛的類型,也是很基礎(chǔ)的類型,C語言并沒有直接處理字符串的操作而是采用字符指針和字符串數(shù)組進行操作,而在C++中標準庫為我們封裝了一個字符串的類供我們使用,使用需要#inlcude <string>頭文件。我們也可以自己模擬實現(xiàn)一個簡單的String類。
在模擬實現(xiàn)String類的過程中,不可避免的會遇到深拷貝淺拷貝的問題,下面就深拷貝淺拷貝做一個簡介。所謂深拷貝淺拷貝,簡單來說就是淺拷貝只是簡單的將值拷貝過來,用一個對象初始化另一個對象,只復制了成員,并沒有復制資源,使兩個對象同時指向了同一資源的。而深拷貝則是將資源和值一塊拷貝過來,此時兩個對象各自占用資源,盡管值相同,但是互不影響。
下面通過代碼進行對比:
//淺拷貝 class String { public: String(const char* s = "") { if (NULL == s) { _pStr = new char[1]; *_pStr = '\0'; } else { _pStr = new char[strlen(s) + 1]; strcpy(_pStr, s); } } String(const String& s) { _pStr = s._pStr; } String& operator=(const String& s) { if (this != &s) { _pStr = s._pStr; } return *this; } ~String() { if (NULL != _pStr) { delete[] _pStr; _pStr = NULL; } } private: char* _pStr; };
//深拷貝 class String { public: String(const char* s = "") { if (NULL == s) { _pStr = new char[1]; *_pStr = '\0'; } else { _pStr = new char[strlen(s) + 1]; strcpy(_pStr, s); } } String(const String& s) : _pStr(new char[strlen(s._pStr) + 1]) { strcpy(_pStr, s._pStr); } String& operator=(const String& s) { if (this != &s) { //先申請空間將s的內(nèi)容拷貝到一個臨時變量再去釋放原有的空間 char* temp = new char[strlen(s._pStr) + 1];//防止申請空間失敗連原有的空間都沒了 strcpy(temp, s._pStr); delete[] _pStr; _pStr = NULL; _pStr = temp; } return *this; } ~String() { if (NULL != _pStr) { delete[] _pStr; _pStr = NULL; } } private: char* _pStr; };
由圖可以看出,淺拷貝使得多個對象指向一塊空間,然而當最后析構(gòu)的時候,比如c先釋放空間,而a,b卻不知道還要釋放空間便會產(chǎn)生重復釋放同一內(nèi)存的錯誤。為此,我們可以對淺拷貝進行一個優(yōu)化,例如在私有成員中加入一個int*
pCount來標記一塊空間被幾個對象占用,當只有一個對象占用如果進行析構(gòu)便可釋放空間,否則只對*pCount--。
//淺拷貝優(yōu)化--帶有計數(shù)版本的String類,用指針指向計數(shù)的空間 class String { public: String(const char* s = "") : _pCount(new int(1)) { if (NULL == s) { _pStr = new char[1]; *_pStr = '\0'; } else { _pStr = new char[strlen(s) + 1]; strcpy(_pStr, s); } } String(const String& s) { _pStr = s._pStr; _pCount = s._pCount; (*_pCount)++; } String& operator=(const String& s) { if (this != &s) { if (--(*_pCount) == 0) { delete[] _pStr; delete _pCount; } _pStr = s._pStr; _pCount = s._pCount; (*_pCount)++; } return *this; } ~String() { if (NULL != _pStr && --(*_pCount) == 0) { delete[] _pStr; delete _pCount; } _pCount = NULL; _pStr = NULL; } private: char* _pStr; int* _pCount; };
最后再給出一種深拷貝的簡潔版本,通過調(diào)用swap來簡化操作,代碼如下:
//深拷貝的簡潔寫法 class String { public: String(const char* s = "") { if (NULL == s) { _pStr = new char[1]; *_pStr = '\0'; } else { _pStr = new char[strlen(s) + 1]; strcpy(_pStr, s); } } String(String& s) :_pStr(NULL)//必須對_pStr初始化,防止釋放隨機值的空間 { String temp(s._pStr); swap(_pStr, temp._pStr); } String& operator=(String& s) { if (this != &s) { swap(_pStr, s._pStr); } return *this; } ~String() { if (NULL != _pStr) { delete[] _pStr; _pStr = NULL; } } private: char* _pStr; };
如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
新聞名稱:詳解C++中String類模擬實現(xiàn)以及深拷貝淺拷貝
文章出自:http://chinadenli.net/article18/ppgpgp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣、面包屑導航、做網(wǎng)站、品牌網(wǎng)站設(shè)計、云服務器、網(wǎng)站設(shè)計
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)