C++面試八股文之std::string實(shí)現(xiàn)方法
某日二師兄參加XXX科技公司的C++工程師開發(fā)崗位第18面:
面試官:
std::string用過吧?二師兄:當(dāng)然用過(廢話,C++程序員就沒有沒用過
std::string的)。面試官:
std::string("hello")+"world"、"hello"+std::string("world")和std::string("hello")+std::string("world")的結(jié)果是什么?為什么?二師兄:前者和后者的結(jié)果都是
std::string的對(duì)象,內(nèi)容是“helloworld\0”,而中間的這個(gè)表達(dá)式無法通過編譯。原因是std::string重載了operator+(const char*)和operator+(const std::string&),但是const char*卻沒有重載operator+運(yùn)算符。面試官:
std::string有兩個(gè)API,resize和reserve,你知道它們之間的區(qū)別嗎?二師兄:
resize對(duì)應(yīng)的是size,resize可以改變字符串的大小。reserve對(duì)應(yīng)的是capacity,reserve只能改變capacity的大小。二師兄:當(dāng)
resize傳入的參數(shù)小于字符串的szie時(shí),多余的字符串會(huì)被截取。當(dāng)reserve傳入的參數(shù)小于capacity時(shí),reserve什么也不會(huì)做。二師兄:當(dāng)
resize傳入的參數(shù)大于字符串的szie時(shí),增加的字符串會(huì)被默認(rèn)初始化。當(dāng)reserve傳入的參數(shù)大于capacity時(shí),capacity會(huì)被擴(kuò)容。面試官:好的??梢酝ㄟ^下標(biāo)訪問
std::string實(shí)例的內(nèi)容嗎?二師兄:可以的,
std::string重載了下標(biāo)運(yùn)算符,可以像數(shù)組一樣通過下標(biāo)運(yùn)算取出某個(gè)字符。面試官:你知道
std::string的at成員方法嗎?二師兄: 嗯,和下標(biāo)運(yùn)算功能相似,不過不用擔(dān)心越界問題??梢园踩脑L問字符串中的字符。
面試官:既然有
at方法了,為什么還要重載下標(biāo)運(yùn)算符呢?二師兄:主要是因?yàn)樾阅苌系目剂俊?code>at雖然保證了不會(huì)超出字符串范圍(超出范圍拋出異常),但是性能低于下標(biāo)操作。這就是有舍有得。為了安全使用
at,為了性能使用下標(biāo)操作。C++給了你多個(gè)選擇,如何選擇看你的需求。面試官:那你知道
std::string是如何實(shí)現(xiàn)的嗎?二師兄:在
string內(nèi)部維護(hù)一個(gè)指針,這個(gè)指針指向真正的字符串的位置。面試官:能簡(jiǎn)單的寫一下實(shí)現(xiàn)代碼嗎?
二師兄:好的。
class string
{
public:
string():size_(0),data_(nullptr){}
explicit string(const char* c)
{
size_ = strlen(c);
data_ = (char*)malloc(size_+1);
memset(data_,0,size_+1);
memcpy(data_,c,size_);
}
size_t size() const {return size_;}
const char* c_str() const {return data_;}
private:
size_t size_;
char* data_;
};二師兄:在實(shí)現(xiàn)
append或者+=的時(shí)候,需要把當(dāng)前字符的長(zhǎng)度加上append的內(nèi)容的長(zhǎng)度,以此長(zhǎng)度申請(qǐng)一塊新內(nèi)存,然后把當(dāng)前字符串的內(nèi)存和append的內(nèi)容考入新申請(qǐng)的內(nèi)存中。free掉之前data_指向的內(nèi)存,然后把data_指針指向新申請(qǐng)的內(nèi)存。面試官:好的。這樣的實(shí)現(xiàn)有一些弊端。如果頻繁的對(duì)一個(gè)
std::string對(duì)象append內(nèi)容,會(huì)發(fā)生什么?二師兄:是的,因?yàn)轭l繁的
malloc和free,會(huì)有性能問題。因所以編譯器在實(shí)現(xiàn)std::string的時(shí)候一般會(huì)預(yù)先申請(qǐng)一塊大的內(nèi)存,這塊內(nèi)存的長(zhǎng)度是capacity,當(dāng)添加的字符串的長(zhǎng)度加上當(dāng)前的字符串長(zhǎng)度小于capacity時(shí),直接添加到當(dāng)前的塊上即可。面試官:好的。針對(duì)字符串比較少的情況,一般編譯器會(huì)做一些優(yōu)化,你知道如何優(yōu)化的嗎?
二師兄:這個(gè)好像在哪看過,不記得額。。。
面試官:好的,今天的面試結(jié)束了,請(qǐng)回去等通知吧。
今天二師兄的表現(xiàn)不錯(cuò),除了最后一個(gè)問題,基本上都答上來了。讓我們來看下這個(gè)問題:
針對(duì)字符串比較少的情況,一般編譯器會(huì)做一些優(yōu)化,你知道如何優(yōu)化的嗎?
我們可以看看GCC中std::string的實(shí)現(xiàn):
typedef basic_string<char> string;
_Alloc_hider _M_dataplus;
size_type _M_string_length;
enum { _S_local_capacity = 15 / sizeof(_CharT) };
union
{
_CharT _M_local_buf[_S_local_capacity + 1];
size_type _M_allocated_capacity;
};這里的_CharT就是char,所以_S_local_capacity等于15。當(dāng)字符串的長(zhǎng)度小于等于15時(shí),直接存在_M_local_buf中,而不需要在堆中申請(qǐng)內(nèi)存。當(dāng)字符串長(zhǎng)度大于15時(shí),在內(nèi)存中申請(qǐng)一塊內(nèi)存,這塊內(nèi)存的起始地址保存在_M_dataplus中,這塊內(nèi)存的容量保存在_M_allocated_capacity 中,而字符串的真實(shí)長(zhǎng)度保存在_M_string_length中。當(dāng)向字符串中添加字符時(shí),如果添加字符的長(zhǎng)度大于 _M_allocated_capacity - _M_string_length,則需要resize,否則直接追加到_M_dataplus保存的內(nèi)存塊中即可。
好了,今天的面試到這里就結(jié)束了。
到此這篇關(guān)于C++面試八股文之std::string實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)C++實(shí)現(xiàn)std::string內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 利用C++實(shí)現(xiàn)從std::string類型到bool型的轉(zhuǎn)換
- C/C++中關(guān)于std::string的compare陷阱示例詳解
- C++ float轉(zhuǎn)std::string 小數(shù)位數(shù)控制問題
- C++17 使用 std::string_view避免字符串拷貝優(yōu)化程序性能
- C++中std::string::npos的用法
- C++17中std::string_view的使用
- C++中std::stringstream多類型數(shù)據(jù)拼接和提取用法小結(jié)
- c++使用 std::string 存儲(chǔ)二進(jìn)制數(shù)據(jù)
相關(guān)文章
C語言指針學(xué)習(xí)經(jīng)驗(yàn)總結(jié)淺談
指針是C語言的難點(diǎn)和重點(diǎn),但指針也是C語言的靈魂 。2013-03-03
如何使用C語言實(shí)現(xiàn)細(xì)菌的繁殖與擴(kuò)散
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)細(xì)菌的繁殖與擴(kuò)散,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11
C++隱式類型轉(zhuǎn)換運(yùn)算符operator type()用法詳解
這篇文章主要介紹了C++隱式類型轉(zhuǎn)換運(yùn)算符operator type()用法詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
Qt使用QChart實(shí)現(xiàn)靜態(tài)顯示溫度變化曲線
QChart模塊是Qt?Charts庫的基礎(chǔ),提供了用于創(chuàng)建和顯示各種類型圖表的類和接口,本文主要介紹了如何使用QChart實(shí)現(xiàn)動(dòng)態(tài)顯示3個(gè)設(shè)備的溫度變化曲線,感興趣的可以了解一下2023-06-06
C語言中qsort函數(shù)使用及其模擬實(shí)現(xiàn)教程
C語言中存在著許多排序函數(shù),如我們熟悉的冒泡函數(shù),還有堆排序、歸并排序等等,這些排序函數(shù)的功能給我們帶來了許多便捷,這篇文章主要介紹了C語言中qsort函數(shù)使用及其模擬實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2025-08-08
C/C++獲取Windows平臺(tái)CPU占用率的方法
最近在做系統(tǒng)信息相關(guān)的接口,為了實(shí)現(xiàn)跨平臺(tái),故在linux和Windows平臺(tái)獲取占用率信息,文章主要介紹Windows下的方法,文中給出了參考代碼,需要的朋友可以參考下2023-12-12

