溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

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

發(fā)布時(shí)間:2020-10-09 00:22:44 來源:腳本之家 閱讀:136 作者:xy913741894 欄目:編程語言

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

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

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

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

//淺拷貝 
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)容拷貝到一個(gè)臨時(shí)變量再去釋放原有的空間 
      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; 
}; 

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

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

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

最后再給出一種深拷貝的簡潔版本,通過調(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初始化,防止釋放隨機(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; 
}; 


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

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI