欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2017年10月31日 15:09:03   作者:xy913741894  
這篇文章主要介紹了詳解C++中String類模擬實現(xiàn)以及深拷貝淺拷貝的相關資料,希望通過本文能幫助到大家,讓大家實現(xiàn)這樣的方法,需要的朋友可以參考下

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

在C語言中/C++中,字符串是一個應用很廣泛的類型,也是很基礎的類型,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; 
}; 


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

    C++虛函數(shù)注意事項

    這篇文章主要給大家分享了EC++虛函數(shù)注意事項,
    2022-01-01
  • 舉例講解C語言鏈接器的符號解析機制

    舉例講解C語言鏈接器的符號解析機制

    鏈接器的工作主要分為兩個階段:符號解析和重定位,符號解析的功能是將每個模塊符號引用綁定到一個確切的符號定義,這里我們就來舉例講解C語言鏈接器的符號解析機制
    2016-05-05
  • 超詳細講解C++的三種函數(shù)傳遞方式

    超詳細講解C++的三種函數(shù)傳遞方式

    這個文章我將把我學習的有關函數(shù)傳遞形式的知識做個總結,相信很多剛入門的同學看到許多文章五花八門的形參會感到頭疼,但本質(zhì)上無非就是我要說的三種傳遞形式,快來跟我一起學習吧
    2022-05-05
  • C++使用ImGUI框架開發(fā)一個簡單程序

    C++使用ImGUI框架開發(fā)一個簡單程序

    ImGui?是一個用于C++的用戶界面庫,跨平臺、無依賴,支持OpenGL、DirectX等多種渲染API,下面就跟隨小編一起學習一下如何使用ImGUI框架開發(fā)一個簡單程序吧
    2023-08-08
  • 詳解Qt中的雙緩沖機制與實例應用

    詳解Qt中的雙緩沖機制與實例應用

    所謂雙緩沖機制,是指在繪制控件時,首先將要繪制的內(nèi)容繪制在一個圖片中,再將圖片一次性地繪制到控件上。本文主要為大家介紹了Qt中的雙緩沖機制與實例應用,希望對大家有所幫助
    2023-03-03
  • C++實現(xiàn)將一個字符串中的字符替換成另一個字符串的方法

    C++實現(xiàn)將一個字符串中的字符替換成另一個字符串的方法

    這篇文章主要介紹了C++實現(xiàn)將一個字符串中的字符替換成另一個字符串的方法,需要考慮的情況比較全面,有不錯的借鑒價值,需要的朋友可以參考下
    2014-09-09
  • C++?二叉樹的實現(xiàn)超詳細解析

    C++?二叉樹的實現(xiàn)超詳細解析

    二叉樹可以簡單理解為對于一個節(jié)點來說,最多擁有一個上級節(jié)點,同時最多具備左右兩個下級節(jié)點的數(shù)據(jù)結構。本文將詳細介紹一下C++中二叉樹的實現(xiàn)和遍歷,需要的可以參考一下
    2022-03-03
  • C++派生類與基類的轉(zhuǎn)換規(guī)則

    C++派生類與基類的轉(zhuǎn)換規(guī)則

    基類與派生類對象之間有賦值兼容關系,由于派生類中包含從基類繼承的成員,具體表現(xiàn)在以下幾個方面,需要的朋友可以參考下
    2012-11-11
  • C++中返回指向函數(shù)的指針示例

    C++中返回指向函數(shù)的指針示例

    int (*ff(int)) (int *,int);表示:ff(int)是一個函數(shù),帶有一個int型的形參,該函數(shù)返回int (*) (int *,int),它是一個指向函數(shù)的指針,所指向的函數(shù)返回int型并帶有兩個分別是Int*和int型的形參
    2013-09-09
  • C/C++?Linux?Socket網(wǎng)絡編程流程分析

    C/C++?Linux?Socket網(wǎng)絡編程流程分析

    這篇文章主要介紹了C/C++?Linux?Socket網(wǎng)絡編程,Linux環(huán)境中的C/C++?socket?與Window環(huán)境中的C/C++?socket類似,本文所記錄的是TCP協(xié)議的socket編程,圖文實例相結合給大家介紹的非常詳細,需要的朋友可以參考下
    2023-02-02

最新評論