国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > C++ > 正文

詳解C++中String類模擬實(shí)現(xiàn)以及深拷貝淺拷貝

2020-05-23 13:39:04
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

詳解C++中String類模擬實(shí)現(xiàn)以及深拷貝淺拷貝

在C語(yǔ)言中/C++中,字符串是一個(gè)應(yīng)用很廣泛的類型,也是很基礎(chǔ)的類型,C語(yǔ)言并沒(méi)有直接處理字符串的操作而是采用字符指針和字符串?dāng)?shù)組進(jìn)行操作,而在C++中標(biāo)準(zhǔn)庫(kù)為我們封裝了一個(gè)字符串的類供我們使用,使用需要#inlcude <string>頭文件。我們也可以自己模擬實(shí)現(xiàn)一個(gè)簡(jiǎn)單的String類。

在模擬實(shí)現(xiàn)String類的過(guò)程中,不可避免的會(huì)遇到深拷貝淺拷貝的問(wèn)題,下面就深拷貝淺拷貝做一個(gè)簡(jiǎn)介。所謂深拷貝淺拷貝,簡(jiǎn)單來(lái)說(shuō)就是淺拷貝只是簡(jiǎn)單的將值拷貝過(guò)來(lái),用一個(gè)對(duì)象初始化另一個(gè)對(duì)象,只復(fù)制了成員,并沒(méi)有復(fù)制資源,使兩個(gè)對(duì)象同時(shí)指向了同一資源的。而深拷貝則是將資源和值一塊拷貝過(guò)來(lái),此時(shí)兩個(gè)對(duì)象各自占用資源,盡管值相同,但是互不影響。

下面通過(guò)代碼進(jìn)行對(duì)比:

//淺拷貝 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) { //先申請(qǐng)空間將s的內(nèi)容拷貝到一個(gè)臨時(shí)變量再去釋放原有的空間       char* temp = new char[strlen(s._pStr) + 1];//防止申請(qǐng)空間失敗連原有的空間都沒(méi)了       strcpy(temp, s._pStr);       delete[] _pStr;       _pStr = NULL;       _pStr = temp;     }     return *this;   }   ~String()   {     if (NULL != _pStr) {       delete[] _pStr;       _pStr = NULL;     }   } private:   char* _pStr; }; 

C++,String類,深拷貝,淺拷貝

C++,String類,深拷貝,淺拷貝

由圖可以看出,淺拷貝使得多個(gè)對(duì)象指向一塊空間,然而當(dāng)最后析構(gòu)的時(shí)候,比如c先釋放空間,而a,b卻不知道還要釋放空間便會(huì)產(chǎn)生重復(fù)釋放同一內(nèi)存的錯(cuò)誤。為此,我們可以對(duì)淺拷貝進(jìn)行一個(gè)優(yōu)化,例如在私有成員中加入一個(gè)int*
 pCount來(lái)標(biāo)記一塊空間被幾個(gè)對(duì)象占用,當(dāng)只有一個(gè)對(duì)象占用如果進(jìn)行析構(gòu)便可釋放空間,否則只對(duì)*pCount--。

//淺拷貝優(yōu)化--帶有計(jì)數(shù)版本的String類,用指針指向計(jì)數(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; }; 

最后再給出一種深拷貝的簡(jiǎn)潔版本,通過(guò)調(diào)用swap來(lái)簡(jiǎn)化操作,代碼如下:

//深拷貝的簡(jiǎn)潔寫(xiě)法 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)//必須對(duì)_pStr初始化,防止釋放隨機(jī)值的空間   {     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; }; 

如有疑問(wèn)請(qǐng)留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 广安市| 神农架林区| 托里县| 阿鲁科尔沁旗| 肃南| 噶尔县| 木兰县| 柳河县| 岳西县| 淳安县| 潞城市| 娄底市| 靖边县| 布尔津县| 故城县| 玉环县| 大宁县| 卢氏县| 汶上县| 界首市| 金坛市| 盐城市| 嘉义市| 甘泉县| 绵阳市| 阿荣旗| 神木县| 永昌县| 绩溪县| 德江县| 集安市| 桃园县| 蓬溪县| 宝鸡市| 丹东市| 华亭县| 蒙城县| 湖口县| 石嘴山市| 南漳县| 通海县|