程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 分享C++面試中string類的一種准確寫法

分享C++面試中string類的一種准確寫法

編輯:關於C++

分享C++面試中string類的一種准確寫法。本站提示廣大學習愛好者:(分享C++面試中string類的一種准確寫法)文章只能為提供參考,不一定能成為您想要的結果。以下是分享C++面試中string類的一種准確寫法正文


詳細來講:

能像 int 類型那樣界說變量,而且支撐賦值、復制。
能用作函數的參數類型及前往類型。
能用作尺度庫容器的元素類型,即 vector/list/deque 的 value_type。(用作 std::map 的 key_type 是更進一步的請求,本文從略)。
換言之,你的 String 能讓以下代碼編譯運轉經由過程,而且沒有內存方面的毛病。


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[] 之類的重載了。

如許代碼根本上就定型了:


#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類的成績》

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved