日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++面试中string类的一种正确写法

發(fā)布時間:2025/3/21 c/c++ 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++面试中string类的一种正确写法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

C++ 的一個常見面試題是讓你實現(xiàn)一個 String 類,限于時間,不可能要求具備 std::string 的功能,但至少要求能正確管理資源。具體來說:

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

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 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)正確性及易實現(xiàn)(白板上寫也不會錯),不強(qiáng)調(diào)效率。某種意義上可以說是以時間(運行快慢)換空間(代碼簡潔)。

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

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

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

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 #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òu)造函數(shù)里調(diào)用 new char[],只在析構(gòu)函數(shù)里調(diào)用 delete[]。
  • 賦值操作符采用了《C++編程規(guī)范》推薦的現(xiàn)代寫法。
  • 每個函數(shù)都只有一兩行代碼,沒有條件判斷。
  • 析構(gòu)函數(shù)不必檢查 data_ 是否為 NULL。
  • 構(gòu)造函數(shù) String(const char* str) 沒有檢查 str 的合法性,這是一個永無止境的爭論話題。這里在初始化列表里就用到了 str,因此在函數(shù)體內(nèi)用 assert() 是無意義的。
  • 這恐怕是最簡潔的 String 實現(xiàn)了。

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

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

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

    陳皓注:同時,大家可以移步看看我的一篇老文《STL中String類的問題》


    from: http://coolshell.cn/articles/10478.html

    總結(jié)

    以上是生活随笔為你收集整理的C++面试中string类的一种正确写法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。