分享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