最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

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

下面通過代碼進行對比:

//淺拷貝 
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; 
}; 


由圖可以看出,淺拷貝使得多個對象指向一塊空間,然而當(dāng)最后析構(gòu)的時候,比如c先釋放空間,而a,b卻不知道還要釋放空間便會產(chǎn)生重復(fù)釋放同一內(nèi)存的錯誤。為此,我們可以對淺拷貝進行一個優(yōu)化,例如在私有成員中加入一個int*
 pCount來標(biāo)記一塊空間被幾個對象占用,當(dāng)只有一個對象占用如果進行析構(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ū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關(guān)文章

  • C++利用inotify+epoll實現(xiàn)異步文件監(jiān)控的方法

    C++利用inotify+epoll實現(xiàn)異步文件監(jiān)控的方法

    這篇文章講給大家詳細介紹一下C++利用inotify+epoll實現(xiàn)異步文件監(jiān)控的方法,inotify是一種異步文件監(jiān)控機制,文章通過代碼示例介紹的非常詳細,具有一定的參考價值,需要的朋友可以參考下
    2023-08-08
  • 深入了解C++中基于模板的類型擦除

    深入了解C++中基于模板的類型擦除

    在C\C++中主要有三種類型擦除的方式:基于void*的類型擦除、面向?qū)ο蟮念愋筒脸突谀0宓念愋筒脸?本文主要為大家詳細介紹基于模板的類型擦除的相關(guān)知識,需要的可以了解下
    2023-12-12
  • C語言函數(shù)調(diào)用底層實現(xiàn)原理分析

    C語言函數(shù)調(diào)用底層實現(xiàn)原理分析

    這篇文章主要介紹了C語言函數(shù)調(diào)用底層實現(xiàn)原理,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • C++超詳細講解智能指針

    C++超詳細講解智能指針

    為了解決內(nèi)存泄漏的問題,C++中提出了智能指針。內(nèi)存泄漏的產(chǎn)生原因有很多,即使我們正確的使用malloc和free關(guān)鍵字也有可能產(chǎn)生內(nèi)存泄漏,如在malloc和free之間如果存在拋異常,那也會產(chǎn)生內(nèi)存泄漏。這種問題被稱為異常安全
    2022-06-06
  • C++基本用法實踐之智能指針詳解

    C++基本用法實踐之智能指針詳解

    為了減少手動管理內(nèi)存帶來的困擾,c++提出了智能指針,可以幫助我們進行內(nèi)存管理,下面小編就來和大家簡單聊聊C++中智能指針的基本用法吧
    2023-07-07
  • C++適用入門同學(xué)的模板講解

    C++適用入門同學(xué)的模板講解

    人們需要編寫多個形式和功能都相似的函數(shù),因此有了函數(shù)模板來減少重復(fù)勞動;人們也需要編寫多個形式和功能都相似的類,于是?C++?引人了類模板的概念,編譯器從類模板可以自動生成多個類,避免了程序員的重復(fù)勞動
    2022-07-07
  • 判斷指定的進程或程序是否存在方法小結(jié)(vc等)

    判斷指定的進程或程序是否存在方法小結(jié)(vc等)

    VC判斷進程是否存在?比如我想知道記事本是否運行,要用到哪些函數(shù)等實例,需要的朋友可以參考下
    2013-01-01
  • C語言文件操作零基礎(chǔ)新手入門保姆級教程

    C語言文件操作零基礎(chǔ)新手入門保姆級教程

    在實際應(yīng)用中,我們往往需要對文件進行操作,下面這篇文章主要給大家分享了關(guān)于C語言文件操作的零基礎(chǔ)新手入門保姆級教程,文中通過示例代碼以及圖片介紹的非常詳細,需要的朋友可以參考下
    2021-10-10
  • C語言基于回溯算法解決八皇后問題的方法

    C語言基于回溯算法解決八皇后問題的方法

    這篇文章主要介紹了C語言基于回溯算法解決八皇后問題的方法,簡單描述了八皇后問題,并結(jié)合實例形式分析了C語言使用回溯算法解決八皇后問題的相關(guān)操作技巧,需要的朋友可以參考下
    2018-06-06
  • C語言文件復(fù)制實例詳解

    C語言文件復(fù)制實例詳解

    這篇文章主要介紹了C語言文件復(fù)制實例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06

最新評論

兴和县| 洛南县| 新干县| 清丰县| 罗甸县| 奉化市| 四平市| 陆川县| 绵阳市| 扶绥县| 大方县| 永定县| 濮阳市| 敖汉旗| 延安市| 南丹县| 吉木萨尔县| 滨海县| 灌南县| 周宁县| 巨鹿县| 家居| 涞水县| 鲁甸县| 凤台县| 右玉县| 正定县| 河西区| 阿拉尔市| 茌平县| 南京市| 河津市| 舞阳县| 云龙县| 高阳县| 遂昌县| 从江县| 芜湖市| 五莲县| 时尚| 南川市|