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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

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

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

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

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

    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"); }

    本文給出我認為適合面試的答案,強調正確性及易實現(白板上寫也不會錯),不強調效率。某種意義上可以說是以時間(運行快慢)換空間(代碼簡潔)。

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

    其次決定支持哪些操作,構造、析構、拷貝構造、賦值這幾樣是肯定要有的(以前合稱 big three,現在叫 copy control)。如果鉆得深一點,C++11的移動構造和移動賦值也可以有。為了突出重點,本文就不考慮 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_; };

    注意代碼的幾個要點:

  • 只在構造函數里調用 new char[],只在析構函數里調用 delete[]。
  • 賦值操作符采用了《C++編程規范》推薦的現代寫法。
  • 每個函數都只有一兩行代碼,沒有條件判斷。
  • 析構函數不必檢查 data_ 是否為 NULL。
  • 構造函數 String(const char* str) 沒有檢查 str 的合法性,這是一個永無止境的爭論話題。這里在初始化列表里就用到了 str,因此在函數體內用 assert() 是無意義的。
  • 這恐怕是最簡潔的 String 實現了。

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

    練習2:實現一個帶 int size_; 成員的版本,以空間換時間。

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

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


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

    總結

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

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。