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

分享C++面試中string類的一種正確寫(xiě)法

 更新時(shí)間:2013年11月06日 22:25:08   作者:  
C++ 的一個(gè)常見(jiàn)面試題是讓你實(shí)現(xiàn)一個(gè) String 類,限于時(shí)間,不可能要求具備 std::string 的功能,但至少要求能正確管理資源

具體來(lái)說(shuō):

能像 int 類型那樣定義變量,并且支持賦值、復(fù)制。
能用作函數(shù)的參數(shù)類型及返回類型。
能用作標(biāo)準(zhǔn)庫(kù)容器的元素類型,即 vector/list/deque 的 value_type。(用作 std::map 的 key_type 是更進(jìn)一步的要求,本文從略)。
換言之,你的 String 能讓以下代碼編譯運(yùn)行通過(guò),并且沒(méi)有內(nèi)存方面的錯(cuò)誤。

復(fù)制代碼 代碼如下:

void foo(String x) 



void bar(const String& x) 



String baz() 

  String ret("world"); 
  return ret; 


int main() 

  String s0; 
  String s1("hello"); 
  String s2(s0); 
  String s3 = s1; 
  s2 = s1; 

  foo(s1); 
  bar(s1); 
  foo("temporary"); 
  bar("temporary"); 
  String s4 = baz(); 

  std::vector<String> svec; 
  svec.push_back(s0); 
  svec.push_back(s1); 
  svec.push_back(baz()); 
  svec.push_back("good job"); 
}

本文給出我認(rèn)為適合面試的答案,強(qiáng)調(diào)正確性及易實(shí)現(xiàn)(白板上寫(xiě)也不會(huì)錯(cuò)),不強(qiáng)調(diào)效率。某種意義上可以說(shuō)是以時(shí)間(運(yùn)行快慢)換空間(代碼簡(jiǎn)潔)。

首先選擇數(shù)據(jù)成員,最簡(jiǎn)單的 String 只有一個(gè) char* 成員變量。好處是容易實(shí)現(xiàn),壞處是某些操作的復(fù)雜度較高(例如 size() 會(huì)是線性時(shí)間)。為了面試時(shí)寫(xiě)代碼不出錯(cuò),本文設(shè)計(jì)的 String 只有一個(gè) char* data_成員。而且規(guī)定 invariant 如下:一個(gè) valid 的 string 對(duì)象的 data_ 保證不為 NULL,data_ 以 '\0' 結(jié)尾,以方便配合 C 語(yǔ)言的 str*() 系列函數(shù)。

其次決定支持哪些操作,構(gòu)造、析構(gòu)、拷貝構(gòu)造、賦值這幾樣是肯定要有的(以前合稱 big three,現(xiàn)在叫 copy control)。如果鉆得深一點(diǎn),C++11的移動(dòng)構(gòu)造和移動(dòng)賦值也可以有。為了突出重點(diǎn),本文就不考慮 operator[] 之類的重載了。

這樣代碼基本上就定型了:

復(fù)制代碼 代碼如下:

#include <utility> 
#include <string.h> 

class String 

 public: 
  String() 
    : data_(new char[1]) 
  { 
    *data_ = '\0'; 
  } 

  String(const char* str) 
    : data_(new char[strlen(str) + 1]) 
  { 
    strcpy(data_, str); 
  } 

  String(const String& rhs) 
    : data_(new char[rhs.size() + 1]) 
  { 
    strcpy(data_, rhs.c_str()); 
  } 
  /* Delegate constructor in C++11 
  String(const String& rhs) 
    : String(rhs.data_) 
  { 
  } 
  */ 

  ~String() 
  { 
    delete[] data_; 
  } 

  /* Traditional: 
  String& operator=(const String& rhs) 
  { 
    String tmp(rhs); 
    swap(tmp); 
    return *this; 
  } 
  */ 
  String& operator=(String rhs) // yes, pass-by-value 
  { 
    swap(rhs); 
    return *this; 
  } 

  // C++ 11 
  String(String&& rhs) 
    : data_(rhs.data_) 
  { 
    rhs.data_ = nullptr; 
  } 

  String& operator=(String&& rhs) 
  { 
    swap(rhs); 
    return *this; 
  } 

  // Accessors 

  size_t size() const 
  { 
    return strlen(data_); 
  } 

  const char* c_str() const 
  { 
    return data_; 
  } 

  void swap(String& rhs) 
  { 
    std::swap(data_, rhs.data_); 
  } 

 private: 
  char* data_; 
};

注意代碼的幾個(gè)要點(diǎn):

只在構(gòu)造函數(shù)里調(diào)用 new char[],只在析構(gòu)函數(shù)里調(diào)用 delete[]。
賦值操作符采用了《C++編程規(guī)范》推薦的現(xiàn)代寫(xiě)法。
每個(gè)函數(shù)都只有一兩行代碼,沒(méi)有條件判斷。
析構(gòu)函數(shù)不必檢查 data_ 是否為 NULL。
構(gòu)造函數(shù) String(const char* str) 沒(méi)有檢查 str 的合法性,這是一個(gè)永無(wú)止境的爭(zhēng)論話題。這里在初始化列表里就用到了 str,因此在函數(shù)體內(nèi)用 assert() 是無(wú)意義的。
這恐怕是最簡(jiǎn)潔的 String 實(shí)現(xiàn)了。

練習(xí)1:增加 operator==、operator<、operator[] 等操作符重載。

練習(xí)2:實(shí)現(xiàn)一個(gè)帶 int size_; 成員的版本,以空間換時(shí)間。

練習(xí)3:受益于右值引用及移動(dòng)語(yǔ)意,在 C++11 中對(duì) String 實(shí)施直接插入排序的性能比C++98/03要高,試編程驗(yàn)證之。(g++的標(biāo)準(zhǔn)庫(kù)也用到了此技術(shù)。)

陳皓注:同時(shí),大家可以移步看看我的一篇老文《STL中String類的問(wèn)題

原文鏈接:http://coolshell.cn/articles/10478.html

相關(guān)文章

  • C++實(shí)現(xiàn)LeetCode(83.移除有序鏈表中的重復(fù)項(xiàng))

    C++實(shí)現(xiàn)LeetCode(83.移除有序鏈表中的重復(fù)項(xiàng))

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(83.移除有序鏈表中的重復(fù)項(xiàng)),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • Qt讀寫(xiě)ini文件之QSettings用法

    Qt讀寫(xiě)ini文件之QSettings用法

    這篇文章主要為大家介紹了Qt讀寫(xiě)ini文件之QSettings的使用方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • C++11/14 線程的創(chuàng)建與分離的實(shí)現(xiàn)

    C++11/14 線程的創(chuàng)建與分離的實(shí)現(xiàn)

    這篇文章主要介紹了C++11/14 線程的創(chuàng)建與分離的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-01-01
  • c++中queue用法超詳細(xì)講解(入門必看!)

    c++中queue用法超詳細(xì)講解(入門必看!)

    queue是一種容器轉(zhuǎn)換器模板,調(diào)用#include< queue>即可使用隊(duì)列類,下面這篇文章主要給大家介紹了關(guān)于c++中queue用法超詳細(xì)講解的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • C/C++內(nèi)存泄漏原因分析與應(yīng)對(duì)方法

    C/C++內(nèi)存泄漏原因分析與應(yīng)對(duì)方法

    內(nèi)存泄漏會(huì)導(dǎo)致當(dāng)前應(yīng)用程序消耗更多的內(nèi)存,使得其他應(yīng)用程序可用的內(nèi)存更少了,那么為什么會(huì)內(nèi)存泄漏,我們應(yīng)該怎樣應(yīng)對(duì)內(nèi)存泄漏,所以接下來(lái)就給大家詳細(xì)介紹一下C++內(nèi)存泄漏原因分析與應(yīng)對(duì)方法,需要的朋友可以參考下
    2023-07-07
  • vc中使用SendMessage自定義消息函數(shù)

    vc中使用SendMessage自定義消息函數(shù)

    這篇文章主要介紹了vc中使用SendMessage自定義消息函數(shù)的相關(guān)資料,需要的朋友可以參考下
    2015-06-06
  • 擴(kuò)展KMP算法(Extend KMP)

    擴(kuò)展KMP算法(Extend KMP)

    我們這里說(shuō)的KMP不是拿來(lái)放電影的(雖然我很喜歡這個(gè)軟件),而是一種算法。KMP算法是拿來(lái)處理字符串匹配的。今天我們談到的是對(duì)KMP算法的拓展
    2014-08-08
  • C++宏函數(shù)和內(nèi)聯(lián)函數(shù)的使用

    C++宏函數(shù)和內(nèi)聯(lián)函數(shù)的使用

    本文主要介紹了C++宏函數(shù)和內(nèi)聯(lián)函數(shù)的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之二分法查找詳解

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之二分法查找詳解

    二分查找算法是在有序數(shù)組中用到的較為頻繁的一種算法,在未接觸二分查找算法時(shí),最通用的一種做法是,對(duì)數(shù)組進(jìn)行遍歷,跟每個(gè)元素進(jìn)行比較,其時(shí)間為O(n),但二分查找算法更優(yōu)
    2022-02-02
  • C++中set的用法學(xué)習(xí)

    C++中set的用法學(xué)習(xí)

    Set是C++?STL(標(biāo)準(zhǔn)模板庫(kù))的一個(gè)容器類,它用于存儲(chǔ)不同的值,并且可以按照特定順序進(jìn)行訪問(wèn)和操作。本文就來(lái)通過(guò)一些示例和大家簡(jiǎn)單講講set的用法吧
    2023-05-05

最新評(píng)論

丹寨县| 渝北区| 依安县| 阿巴嘎旗| 资中县| 孝感市| 梁山县| 开平市| 砚山县| 吉隆县| 中宁县| 玉溪市| 通渭县| 汽车| 香河县| 玛沁县| 大悟县| 调兵山市| 永春县| 桐乡市| 定日县| 平塘县| 内丘县| 鄂伦春自治旗| 罗田县| 福泉市| 仙桃市| 内丘县| 三原县| 伊通| 平乡县| 溧水县| 南江县| 鹤岗市| 金平| 绥德县| 唐河县| 阳新县| 兴城市| 九江市| 依兰县|