国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn)

這篇具有很好參考價(jià)值的文章主要介紹了【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

目錄

string類(lèi)的模擬實(shí)現(xiàn)

經(jīng)典的string類(lèi)問(wèn)題

淺拷貝

深拷貝

寫(xiě)時(shí)拷貝(了解)

構(gòu)造函數(shù)

string的全缺省的構(gòu)造函數(shù):

string的拷貝構(gòu)造函數(shù)

傳統(tǒng)寫(xiě)法

現(xiàn)代寫(xiě)法

string的賦值重載函數(shù)

傳統(tǒng)寫(xiě)法

現(xiàn)代寫(xiě)法

string的無(wú)參構(gòu)造函數(shù):

遍歷函數(shù)

operator[ ]

迭代器

迭代器的底層實(shí)現(xiàn)begin和end:

范圍for的使用

修改字符串相關(guān)函數(shù):

reserve?

push_back

append

operator+=

insert(字符的版本)

insert(字符串常量)

erase

resize

find(查找單個(gè)字符)

find(查找子串)

substr

比較運(yùn)算符的重載:

流插入cout

流提取cin

優(yōu)化寫(xiě)法

clear


前言:

??個(gè)人博客:Dream_Chaser

??博客專(zhuān)欄:C++

??本篇內(nèi)容:string類(lèi)通用函數(shù)的模擬實(shí)現(xiàn)

string類(lèi)的模擬實(shí)現(xiàn)

經(jīng)典的string類(lèi)問(wèn)題

上面已經(jīng)對(duì)string類(lèi)進(jìn)行了簡(jiǎn)單的介紹,大家只要能夠正常使用即可。在面試中,面試官總喜歡讓學(xué)生自己來(lái)模擬實(shí)現(xiàn)string類(lèi),最主要是實(shí)現(xiàn)string類(lèi)的構(gòu)造、拷貝構(gòu)造、賦值運(yùn)算符重載以及析構(gòu)函數(shù)。大家看下以下string類(lèi)的實(shí)現(xiàn)是否有問(wèn)題?

淺拷貝

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

說(shuō)明:上述String類(lèi)沒(méi)有顯式定義其拷貝構(gòu)造函數(shù)與賦值運(yùn)算符重載,此時(shí)編譯器會(huì)合成默認(rèn)的,當(dāng)用s1構(gòu) 造s2時(shí),編譯器會(huì)調(diào)用默認(rèn)的拷貝構(gòu)造。最終導(dǎo)致的問(wèn)題是,s1、s2共用同一塊內(nèi)存空間,在釋放時(shí)同一塊 空間被釋放多次而引起程序崩潰,這種拷貝方式,稱(chēng)為淺拷貝。

淺拷貝

淺拷貝:也稱(chēng)位拷貝,編譯器只是將對(duì)象中的值拷貝過(guò)來(lái)。如果對(duì)象中管理資源,最后就會(huì)導(dǎo)致多個(gè)對(duì)象共 享同一份資源,當(dāng)一個(gè)對(duì)象銷(xiāo)毀時(shí)就會(huì)將該資源釋放掉,而此時(shí)另一些對(duì)象不知道該資源已經(jīng)被釋放,以為 還有效,所以當(dāng)繼續(xù)對(duì)資源進(jìn)項(xiàng)操作時(shí),就會(huì)發(fā)生發(fā)生了訪問(wèn)違規(guī)。

深拷貝

如果一個(gè)類(lèi)中涉及到資源的管理,其拷貝構(gòu)造函數(shù)、賦值運(yùn)算符重載以及析構(gòu)函數(shù)必須要顯式給出。一般情況都是按照深拷貝方式提供。

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

寫(xiě)時(shí)拷貝(了解)

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

寫(xiě)時(shí)拷貝就是一種拖延癥,是在淺拷貝的基礎(chǔ)之上增加了引用計(jì)數(shù)的方式來(lái)實(shí)現(xiàn)的。

引用計(jì)數(shù):用來(lái)記錄資源使用者的個(gè)數(shù)。在構(gòu)造時(shí),將資源的計(jì)數(shù)給成1,每增加一個(gè)對(duì)象使用該資源,就給計(jì)數(shù)增加1,當(dāng)某個(gè)對(duì)象被銷(xiāo)毀時(shí),先給該計(jì)數(shù)減1,然后再檢查是否需要釋放資源,如果計(jì)數(shù)為1,說(shuō)明該對(duì)象時(shí)資源的最后一個(gè)使用者,將該資源釋放;否則就不能釋放,因?yàn)檫€有其他對(duì)象在使用該資源。

構(gòu)造函數(shù)

string的全缺省的構(gòu)造函數(shù):

我們對(duì)string成員函數(shù)進(jìn)行模擬實(shí)現(xiàn)的時(shí)候,首先要定義一個(gè)自定義的命名空間,避免與庫(kù)里面的沖突:

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

讓我們來(lái)看看錯(cuò)誤的案例:

①注意常量字符串的用法,權(quán)限不能放大:

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

②嘗試給_str聲明加上const,這樣就會(huì)導(dǎo)致初始化的時(shí)候出現(xiàn)隨機(jī)值:

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

③需要注意的是"string.h"要定義在std的下方:

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

那么帶參的構(gòu)造可以怎么寫(xiě)呢?初始化列表的順序應(yīng)該對(duì)應(yīng)著成員變量聲明的順序

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

string帶參的構(gòu)造是否可以再優(yōu)化一下呢?

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

注意new的時(shí)候的+1是為了給'\0'預(yù)留的空間:

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

代碼實(shí)現(xiàn):

此構(gòu)造函數(shù)接受一個(gè)可選參數(shù)(默認(rèn)為空字符串),用于初始化一個(gè)字符串對(duì)象,根據(jù)傳入的C風(fēng)格字符串(const char* 類(lèi)型)計(jì)算其長(zhǎng)度,并據(jù)此分配內(nèi)存空間,最后,將傳入的字符串內(nèi)容復(fù)制到新分配的內(nèi)存區(qū)域,以便在C++字符串類(lèi)中進(jìn)行管理。

//構(gòu)造函數(shù),用于初始化一個(gè)字符串類(lèi)對(duì)象
string(const char* str = "")
			:_size(strlen(str))// 初始化_size成員變量,存儲(chǔ)傳入C風(fēng)格字符串(char數(shù)組)str的長(zhǎng)度
			, _capacity(_size)// 初始化_capacity成員變量,初始容量與傳入字符串長(zhǎng)度相同
		{
			_str = new char[_capacity + 1];// 動(dòng)態(tài)分配內(nèi)存,為字符串對(duì)象分配一個(gè)新的字符數(shù)組
			strcpy(_str, str); // 使用strcpy將傳入的字符串str復(fù)制到新分配的字符數(shù)組中
		}

string的拷貝構(gòu)造函數(shù)

傳統(tǒng)寫(xiě)法

//傳統(tǒng)寫(xiě)法 -- 拷貝構(gòu)造
//s2(s1)
string(const string& s)
{
	_str = new char[s._capacity + 1];//僅僅開(kāi)空間
	strcpy(_str, s._str);//
	_size = s._size;
	_capacity = s._capacity;
}

現(xiàn)代寫(xiě)法

// 定義交換函數(shù),將當(dāng)前字符串對(duì)象與輸入?yún)?shù)s的內(nèi)部數(shù)據(jù)(字符數(shù)組、長(zhǎng)度及容量)進(jìn)行交換
void swap(string& s) {
    // 使用STL中的std::swap交換三個(gè)關(guān)鍵成員變量
    std::swap(_str, s._str);
    std::swap(_size, s._size);
    std::swap(_size, s._capacity);
}

// 構(gòu)造函數(shù),復(fù)制輸入?yún)?shù)s的字符串內(nèi)容
// 使用臨時(shí)字符串對(duì)象tmp存儲(chǔ)s的內(nèi)容,然后通過(guò)調(diào)用swap函數(shù)交換數(shù)據(jù)
string(const string& s) :
    _str(nullptr),
    _size(0),
    _capacity(0)
{
    string tmp(s._str); // 創(chuàng)建臨時(shí)字符串tmp,拷貝s的內(nèi)容
    swap(tmp); // 交換當(dāng)前對(duì)象與tmp的數(shù)據(jù),實(shí)現(xiàn)深拷貝
}

string的賦值重載函數(shù)

傳統(tǒng)寫(xiě)法

//傳統(tǒng)寫(xiě)法--賦值重載
// 使得可以使用 "s2 = s3" 的形式,將 s3 字符串對(duì)象的值賦給 s2
string& operator=(const string& s)
{
    // 檢查是否為自我賦值,即檢查是否同一個(gè)對(duì)象
    if (this != &s)
    {
        // 創(chuàng)建一個(gè)臨時(shí)字符數(shù)組 tmp,大小為 s 的容量加一(包含結(jié)束符 '\0')
        char* tmp = new char[s._capacity + 1];

        // 使用 strcpy 函數(shù)將 s 的內(nèi)部字符串復(fù)制到臨時(shí)數(shù)組 tmp 中
        strcpy(tmp, s._str);

        // 刪除當(dāng)前對(duì)象已有的內(nèi)部字符串?dāng)?shù)組
        delete[] _str;

        // 將臨時(shí)數(shù)組 tmp 的地址賦給當(dāng)前對(duì)象的內(nèi)部字符串指針 _str
        _str = tmp;

        // 將源字符串對(duì)象 s 的大小賦給當(dāng)前對(duì)象的大小屬性 _size
        _size = s._size;

        // 同樣將源字符串對(duì)象 s 的容量賦給當(dāng)前對(duì)象的容量屬性 _capacity
        _capacity = s._capacity;
    }

    // 返回當(dāng)前對(duì)象的引用,以支持連續(xù)賦值如 "s1 = s2 = s3"
    return *this;
}

現(xiàn)代寫(xiě)法

// 重載賦值運(yùn)算符,實(shí)現(xiàn)字符串對(duì)象之間的深拷貝賦值操作
string& operator=(const string& s)
{
    // 檢查是否自我賦值(即源對(duì)象與目標(biāo)對(duì)象相同),避免不必要的資源釋放與重新分配
    if (this != &s)
    {
        // 創(chuàng)建臨時(shí)字符串對(duì)象tmp,并使用s的內(nèi)容初始化
        string tmp(s);

        // 調(diào)用自定義的swap函數(shù),將當(dāng)前對(duì)象的數(shù)據(jù)與臨時(shí)對(duì)象tmp的數(shù)據(jù)進(jìn)行交換
        // 這樣可以確保原對(duì)象的資源被正確釋放,并且新內(nèi)容被賦值給當(dāng)前對(duì)象
        swap(tmp);
        
        // 注:這里原本可能是 "this->swap(tmp);",但因?yàn)?"swap" 是成員函數(shù),
        // 在成員函數(shù)內(nèi)部可以直接調(diào)用,無(wú)需 "this->"。
    }

    // 返回當(dāng)前對(duì)象的引用,以便支持連續(xù)賦值操作
    return *this;
}

現(xiàn)代寫(xiě)法優(yōu)化

//現(xiàn)代寫(xiě)法優(yōu)化
string& operator=(string tmp)
{
	swap(tmp);
	return *this;
}

string的無(wú)參構(gòu)造函數(shù):

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

經(jīng)過(guò)嘗試之后,可以發(fā)現(xiàn)以下問(wèn)題:

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

無(wú)參的構(gòu)造應(yīng)該這樣寫(xiě):

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

代碼實(shí)現(xiàn): 建議只寫(xiě)一個(gè)全缺省的構(gòu)造函數(shù)即可,因?yàn)槟J(rèn)構(gòu)造函數(shù)只能存在一個(gè)。

String()
	:_str(new char[1]{'\0'})//數(shù)組的初始化方式
	,_size(0)
	,_capacity(0)
	{}

遍歷函數(shù)

c_str函數(shù)

簡(jiǎn)要說(shuō)明

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

const char* c_str()const
{
	return _str;
}

operator[ ]

這里要演示的話就得遍歷這個(gè)字符串,需要重載一下operator[ ]:

	void test_string1()
	{
		string s1("hello world");
		cout << s1.c_str() << endl;

		string s2;
		cout << s2.c_str() << endl;

		for (size_t i = 0; i < s1.size(); i++)
		{
			cout << s1[i] << " ";
		}
		cout << endl;
}

需要區(qū)分只能讀和可讀可寫(xiě)的版本:

//可讀可寫(xiě)
char& operator[](size_t pos)
{
	assert(pos < _size);
	return _str[pos];
}

//只能讀
const char& operator[](size_t pos)const
{
	assert(pos < _size);
	return _str[pos];
}

代碼執(zhí)行:?

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

既然說(shuō)到遍歷數(shù)組的話,那就少不了迭代器。

迭代器

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

迭代器聲明:?

//聲明
typedef char* iterator;//可讀可寫(xiě)
typedef const char* const_iterator;//只可讀

迭代器的底層實(shí)現(xiàn)begin和end:

begin:函數(shù)的作用就是返回字符串中第一個(gè)字符的地址

//實(shí)現(xiàn):
iterator begin()
{
	return _str;
}

const_iterator begin()const
{
	return _str;
}

end函數(shù)的作用就是返回字符串中最后一個(gè)字符的后一個(gè)字符的地址(即’\0’的地址)

//實(shí)現(xiàn):
iterator end()
{
	return _str + _size;//指向'\0'
}
const_iterator end()const
{
	return _str + _size;//指向'\0'
}

迭代器外層調(diào)用:

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

范圍for的使用

同時(shí)為了方便理解,把范圍for的實(shí)現(xiàn)列舉出來(lái):

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

當(dāng)咱們將begin改為Begin時(shí),發(fā)現(xiàn)會(huì)出錯(cuò),還有一個(gè)點(diǎn):范圍for的本質(zhì)是迭代器

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

迭代器與范圍for的應(yīng)用:?

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

怎么能夠讓改變后的字符串,不再變回原來(lái)的字符串呢?使用引用即可:

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

實(shí)例代碼:

void test_string1()
	{
		string s1("hello world");
		cout << s1.c_str() << endl;

		string s2;
		cout << s2.c_str() << endl;

	/*	for (size_t i = 0; i < s1.size(); i++)
		{
			cout << s1[i] << " ";
		}
		cout << endl;*/

		string::iterator it = s1.begin();
		while (it != s1.end())
		{
			(*it)++;
			cout << *it << " ";
			++it;
		}
		cout << endl;
		for (auto& ch : s1)//使用引用
		{
			ch++;//讓字符串里每個(gè)字符的ascll碼值+1
			cout << ch << " ";
		}
		cout << endl;
		cout << s1.c_str() << endl;
	}

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

修改字符串相關(guān)函數(shù):

reserve?

????????其主要作用是預(yù)先為容器分配足夠的未使用容量,以應(yīng)對(duì)未來(lái)可能的元素添加,而不立即改變?nèi)萜鞯拇笮。ㄔ財(cái)?shù)量)。使用?reserve()?可以有策略地控制容器的內(nèi)存分配,提高連續(xù)添加元素時(shí)的效率

void reserve(size_t n)
{
	// 檢查請(qǐng)求的容量n是否大于當(dāng)前內(nèi)部緩沖區(qū)的實(shí)際容量(_capacity)
	if (n > _capacity)
	{
	 // 如果是,則需要重新分配更大的內(nèi)存空間。新分配的內(nèi)存大小為n+1,+1用于存儲(chǔ)結(jié)尾的空字符'\0
	    char* tmp  = new char[n + 1];//+1存“\0'
	    strcpy(tmp,_str);//將當(dāng)前字符串內(nèi)容(包括結(jié)尾的'\0')復(fù)制到新分配的tmp緩沖區(qū)中
	    delete[] _str;// 釋放原有的內(nèi)部緩沖區(qū)(_str),以避免內(nèi)存泄漏
	    _str = tmp;// 更新內(nèi)部緩沖區(qū)指針,指向新分配的tmp緩沖區(qū)
	    _capacity = n;// 更新內(nèi)部記錄的緩沖區(qū)容量為請(qǐng)求的值n
	 }
}

push_back

? push_back()?是序列容器(如?std::vector,?std::list,?std::deque?等)的成員函數(shù),用于在容器末尾添加新元素。它自動(dòng)處理內(nèi)存管理,確保新元素順利加入,且保持原有元素順序不變。對(duì)于動(dòng)態(tài)擴(kuò)容容器(如?std::vector),在必要時(shí)會(huì)自動(dòng)增大容量。?

嘗試:可以寫(xiě)成這樣嗎?不行,當(dāng)_capacity = 0 時(shí),空間還沒(méi)分配到,此時(shí)如果訪問(wèn)就屬于越界訪問(wèn)

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

代碼實(shí)現(xiàn):

void push_back(char ch)
{
	// 檢查當(dāng)前內(nèi)部字符串長(zhǎng)度(_size)是否已達(dá)到內(nèi)部緩沖區(qū)容量(_capacity)
	if (_size == _capacity)
	{
	    // 若已滿(mǎn),調(diào)用reserve函數(shù)預(yù)分配新的內(nèi)存,擴(kuò)大容量。
		// 首次擴(kuò)容時(shí)容量設(shè)為4,后續(xù)擴(kuò)容按當(dāng)前容量翻倍。
			reserve(_capacity == 0 ? 4 : 2 * _capacity);
	}
		// 將待添加字符ch 存儲(chǔ)在 內(nèi)部字符串緩沖區(qū)的當(dāng)前長(zhǎng)度索引處(_size)
	         _str[_size] = ch;
			 ++_size;// 更新內(nèi)部字符串長(zhǎng)度(_size),增1以包含新添加的字符
			 _str[_size] = '\0';// 在新添加字符之后添加空字符('\0'),確保字符串正確終止
}

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

append

對(duì)于std::string:append()用于在字符串末尾追加其他字符串、字符數(shù)組或單個(gè)字符,可以指定追加的起始位置和長(zhǎng)度。

void append(const char* str)
{
	int len = strlen(str);// 獲取輸入字符串str長(zhǎng)度
	// 檢查是否需擴(kuò)大內(nèi)部緩沖區(qū)容量以容納追加的str
	if (_size + len > _capacity)
	{
		reserve(_size + len);
	}
		//這個(gè)地方要是忘記 +_size,從頭到尾覆蓋新字符串
		strcpy(_str+_size,str);// 將str追加到內(nèi)部字符串緩沖區(qū)末尾
		_size += len;// 更新內(nèi)部字符串長(zhǎng)度
}

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

push_backappend 的區(qū)別在于一個(gè)追加字符,另一個(gè)追加字符串

示例:

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

operator+=

+=運(yùn)算符的重載:分別復(fù)用了 push_back? 和? append,?實(shí)現(xiàn)字符串與字符,字符串與字符串之間能夠直接使用+=運(yùn)算符進(jìn)行尾插。

字符串追加字符:

string& operator+=(char ch)
{
	push_back(ch);
	return *this;
}

字符串追加字符串:

string& operator+=(const char* str)
{
	append(str);
	return *this;
}

示例運(yùn)行:
【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

void test_string2 ()
{
	string s1("hello world");
	s1 += '#';
	s1 += "css";
	cout << s1.c_str() << endl;

	string s2;
	s2 += '#';
	s2 += "csgo";
	cout << s2.c_str() << endl;
}

insert(字符的版本)

嘗試寫(xiě)一下insert:

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

測(cè)試一下代碼的可行性:

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言?可以發(fā)現(xiàn)頭插會(huì)出錯(cuò):

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

頭插:

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

那就換成有符號(hào),此時(shí)pos為0,end為-1,此時(shí)end<pos,但是依然進(jìn)入了循環(huán),明顯的不對(duì)吧,這里是發(fā)生了類(lèi)型轉(zhuǎn)換,end變成無(wú)符號(hào)整型了。

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

怎么解決呢:以下兩種寫(xiě)法都是正確的:

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

此時(shí)函數(shù)的功能:

在動(dòng)態(tài)字符數(shù)組?_str?的指定位置?pos?插入一個(gè)字符?ch。首先,它驗(yàn)證插入位置的有效性(必須小于等于當(dāng)前數(shù)組大小_size)。

若當(dāng)前數(shù)組容量已滿(mǎn),函數(shù)會(huì)自動(dòng)擴(kuò)容,初始容量為4或者當(dāng)前容量的兩倍。

然后,函數(shù)通過(guò)循環(huán)將?pos位置之后的所有元素向右移動(dòng)一位,為新字符騰出空間。

最后,函數(shù)在指定位置pos插入字符ch,并將數(shù)組大小_size加一,表示數(shù)組元素?cái)?shù)量增加。?

//上圖的版本二
void insert(size_t pos, char ch)
{
	assert(pos <= _size);
	if (_size == _capacity)
	{
		reserve(_capacity == 0 ? 4 : 2 * _capacity);
	}
	size_t end = _size + 1;
	while (end > pos)
	{
		_str[end] = _str[end - 1];
		--end;
	}
    _str[pos] = ch;
	_size++;
}

insert(字符串常量)

該函數(shù)的作用:

????????用于在動(dòng)態(tài)字符數(shù)組(或類(lèi)似字符串結(jié)構(gòu))的指定位置pos插入一個(gè)C風(fēng)格字符串str。首先,它通過(guò)斷言確保插入位置的有效性。

????????接著計(jì)算待插入字符串的長(zhǎng)度,并檢查現(xiàn)有容量是否足夠容納插入后的完整字符串,不足則調(diào)用reserve進(jìn)行擴(kuò)容。

????????然后,函數(shù)將插入位置之后的所有字符向右移動(dòng)適當(dāng)距離,為新字符串騰出空間。最后,使用strncpy函數(shù)將待插入字符串復(fù)制到目標(biāo)位置,并更新整個(gè)字符串的大小,反映出新增字符的影響。

首先要注意:

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

所以需要強(qiáng)轉(zhuǎn):

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

//   pos:插入位置,從0開(kāi)始計(jì)數(shù)
//   str:要插入的C風(fēng)格字符串

void insert(size_t pos, const char* str)
{
    // 斷言檢查,確保插入位置pos不大于當(dāng)前字符串的大小
    assert(pos <= _size);

    // 獲取要插入字符串str的長(zhǎng)度,即需要移動(dòng)的字符數(shù)量
    size_t len = strlen(str);

    // 檢查插入后字符串總長(zhǎng)度是否超過(guò)當(dāng)前容量,如果超過(guò)則進(jìn)行擴(kuò)容
    if (_size + len > _capacity)
    {
        reserve(_size + len);  // 調(diào)用reserve函數(shù)來(lái)增加內(nèi)部緩沖區(qū)的容量
    }

    // 數(shù)據(jù)挪動(dòng)部分:
    // 將插入位置pos之后的所有字符向右移動(dòng)len個(gè)位置
    int end = static_cast<int>(_size);  // 使用int類(lèi)型方便進(jìn)行減操作,注意這里假設(shè)_size不會(huì)超出int表示范圍
    while (end >= static_cast<int>(pos))
    {
        _str[end + len] = _str[end];  // 將原字符串中下標(biāo)為end的字符移動(dòng)到end + len的位置
        --end;                        // 移動(dòng)指針至下一個(gè)待移動(dòng)的字符
    }

    // 在指定位置pos處插入字符串str
    strncpy(_str + pos, str, len);  // 使用 strncpy 函數(shù)將str復(fù)制到目標(biāo)字符串相應(yīng)位置

    // 更新字符串的大小
    _size += len;  // 插入操作完成后,字符串的新長(zhǎng)度應(yīng)增加len
}

erase

? ? ? ? 作用是從動(dòng)態(tài)字符數(shù)組(或類(lèi)字符串結(jié)構(gòu))的特定位置pos開(kāi)始刪除指定長(zhǎng)度len的子串。

????????首先,它通過(guò)斷言確保刪除起始位置的有效性(小于當(dāng)前字符串長(zhǎng)度_size)。根據(jù)傳入的參數(shù),函數(shù)會(huì)判斷是否需要?jiǎng)h除從pos到結(jié)尾的所有字符,

????????如果是,則將pos位置之后的字符置為結(jié)束符\0,并將字符串大小更新為pos;否則,將從pos+len開(kāi)始到結(jié)尾的字符依次向前移動(dòng)len個(gè)位置以覆蓋待刪除區(qū)域,并相應(yīng)減少字符串大小_size。

????????簡(jiǎn)而言之,該函數(shù)實(shí)現(xiàn)了對(duì)字符串的指定范圍擦除操作。

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

// 函數(shù):刪除指定位置起始的子串,若未指定長(zhǎng)度,默認(rèn)刪除到字符串末尾
void erase(size_t pos, size_t len = npos)
{
    // 檢查刪除起始位置是否合法(必須在當(dāng)前字符串內(nèi))
    assert(pos < _size);

    // 如果未指定長(zhǎng)度或指定長(zhǎng)度使刪除范圍超出字符串末尾,則刪除從pos到字符串末尾的部分
    if (len == npos || pos+len >= _size)
    {
        // 截?cái)嘧址瑢os位置置空字符,字符串長(zhǎng)度變?yōu)閜os
        _str[pos] = '\0';
        _size = pos;
    }
    // 否則,按指定長(zhǎng)度刪除子串
    else
    {
        // 計(jì)算刪除范圍結(jié)束后的新起始位置
        size_t begin = pos + len;

        // 將刪除范圍后的字符逐個(gè)向前移動(dòng)len位,覆蓋待刪除部分
        while (start <= _size)
        {
            _str[begin - len] = _str[begin];
            ++begin;
        }

        // 更新字符串長(zhǎng)度,減少len
        _size -= len;
    }
}

resize

作用: 改變動(dòng)態(tài)字符數(shù)組(或類(lèi)字符串結(jié)構(gòu))的大小,并可選地用指定字符ch填充新添加的空間。

????????若新指定長(zhǎng)度n小于等于當(dāng)前長(zhǎng)度,函數(shù)將截?cái)嘧址?,使其長(zhǎng)度變?yōu)?code>n;

????????若新長(zhǎng)度大于當(dāng)前長(zhǎng)度且可能超過(guò)當(dāng)前容量時(shí),函數(shù)先調(diào)用reserve進(jìn)行擴(kuò)容,然后使用給定字符ch填充新增的字符位置,直到字符串長(zhǎng)度達(dá)到指定的n,并在字符串末尾添加結(jié)束符\0,以確保字符串的完整性和正確性。

????????總之,此函數(shù)靈活地調(diào)整了字符串的長(zhǎng)度,并保持其內(nèi)容的有效性。

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

void resize(size_t n, char ch = '\0')
{
    // 當(dāng)新長(zhǎng)度n小于等于當(dāng)前字符串長(zhǎng)度時(shí),執(zhí)行刪除操作
    if (n <= _size)
    {
        // 將第n個(gè)字符設(shè)置為空字符,相當(dāng)于截?cái)嘧址⒏伦址膶?shí)際長(zhǎng)度為n
        _str[n] = '\0';
        _size = n;
    }
    // 當(dāng)新長(zhǎng)度n大于當(dāng)前字符串長(zhǎng)度但小于等于當(dāng)前容量時(shí),或新長(zhǎng)度n大于當(dāng)前容量時(shí)
    else
    {
        // 先調(diào)用reserve函數(shù)確保容量足夠容納新長(zhǎng)度的字符串
        reserve(n);

        // 循環(huán)填充字符,直至字符串長(zhǎng)度達(dá)到n
        while (_size < n)
        {
            _str[_size] = ch; // 使用指定字符ch填充
            ++_size;
        }

        // 最后,在新字符串末尾添加結(jié)束符'\0'
        _str[_size] = '\0';
    }
}

find(查找單個(gè)字符)

// 定義一個(gè)成員方法,用于在當(dāng)前字符串對(duì)象中查找指定字符 ch 的首次出現(xiàn)位置
//ch --  要查找的字符
// 查找的起始位置,默認(rèn)從字符串開(kāi)頭(索引0)開(kāi)始

size_t find(char ch, size_t pos = 0)
{
    // 使用一個(gè)循環(huán)遍歷從 pos 位置開(kāi)始到字符串結(jié)尾的所有字符
    for (size_t i = pos; i < _size; i++) 
    {
        // 檢查當(dāng)前遍歷到的字符是否與要查找的字符 ch 相同
        if (_str[i] == ch) 
        {
            // 如果相同,則返回該字符在字符串中的索引位置
            return i;
        }
    }

    // 若遍歷完整個(gè)指定區(qū)間后仍未找到字符 ch,則返回 npos
    // npos 是一個(gè)特殊的值,通常表示“未找到”或“無(wú)效位置”
    return npos;
}

find(查找子串)

size_t find(const char* sub, size_t pos = 0)
{
    // 使用C語(yǔ)言庫(kù)函數(shù)strstr查找子串sub在當(dāng)前字符串(從pos開(kāi)始的部分)中首次出現(xiàn)的位置
    const char* p = strstr(_str + pos, sub);

    // 如果找到了子串sub,則返回子串首字符在當(dāng)前字符串中的相對(duì)索引(即下標(biāo))
    if (p)
    {
        return p - _str;
    }
    // 若找不到子串,則返回特殊值npos,表示子串不在當(dāng)前字符串中
    else
    {
        return npos;
    }
}

substr

// 定義一個(gè)方法,用于從原始字符串中提取子串
string substr(size_t pos, size_t len /* 默認(rèn)為最大長(zhǎng)度 */) {
    // 創(chuàng)建一個(gè)新字符串 s 來(lái)保存子串
    string s;

    // 計(jì)算子串的結(jié)束位置(默認(rèn)取到原始字符串結(jié)尾)
    size_t end = pos + len;
    if (len == npos || pos + len >= _size) {
        // 若指定長(zhǎng)度超過(guò)原始字符串剩余長(zhǎng)度,則取剩余全部字符
        len = _size - pos;
        end = _size;
    }

    // 為新字符串預(yù)分配足夠內(nèi)存以存放子串
    s.reserve(len);

    // 循環(huán)遍歷原始字符串,從 pos 位置開(kāi)始,復(fù)制到新字符串 s 中,直到結(jié)束位置 end
    for (size_t i = pos; i < end; i++) {
        s += _str[i];
    }

    // 返回包含子串的新字符串 s
    return s;
}

比較運(yùn)算符的重載:

bool operator<(const string& s)const
{
	return strcmp(_str,s._str);
}
bool operator==(const string& s)const
{
	return strcmp(_str, s._str)==0;
}
//<= 復(fù)用<
bool operator<=(const string& s)const
{
	return *this < s || *this == s;
}
//>復(fù)用 !(<=)
bool operator>(const string& s)const
{
	return !(*this < s || *this == s);
}
//>=
bool operator>=(const string& s)const
{
	return !(*this < s);
}

bool operator!=(const string& s)const
{
	return !(*this == s);
}

流插入cout

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

這里的范圍for可以訪問(wèn)嗎?不可以:這里要用const迭代器,因?yàn)槭且粋€(gè)被const修飾的對(duì)象,const迭代器指針本身是可以++(修改)的,指針指向的內(nèi)容不可以被修改:

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言所以要這樣做:

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

代碼:

class string
{
public:
	typedef char* iterator;
	typedef const char* const_iterator;//const迭代器
}

ostream& operator<<(ostream& out, const string& s)
{
/*	for (size_t i = 0; i < s.size(); i++)
{
	   out << s[i];
}*/
    for (auto ch : s)
	   out << ch;
		
	return out;
}

流提取cin

需要注意的地方:

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

那么應(yīng)該這樣去寫(xiě):

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

代碼:?

istream& operator>>(istream& in, string& s)
{
	s.clear();//清理原來(lái)的字符數(shù)據(jù),不然就變成尾插了
	char ch;
	//in >> ch;//拿不到 空格 或者 換行
	ch = in.get();//一個(gè)字符一個(gè)字符的拿
	while (ch != ' ' && ch != '\n')
	{
		s += ch;
		//in >> ch;
		ch = in.get();
	}
		return in;
}

優(yōu)化寫(xiě)法

// 重載輸入流提取運(yùn)算符 >>,使得可以從輸入流(如cin)中讀取一串連續(xù)的非空格和非換行符字符到string對(duì)象s中
istream& operator>>(istream& in, string& s)
{
// 清空目標(biāo)string對(duì)象s,準(zhǔn)備接收新的輸入
s.clear();

// 定義一個(gè)固定大小的緩沖區(qū)buff,用于暫存從輸入流中讀取的字符
    char buff[129];
    size_t i = 0; // 初始化緩沖區(qū)索引為0

// 從輸入流in中獲取第一個(gè)字符
    char ch;
    ch = in.get();

// 當(dāng)讀取到的字符不是空格也不是換行符時(shí),繼續(xù)循環(huán)
while (ch != ' ' && ch != '\n')
{
    // 將字符放入緩沖區(qū)
    buff[i++] = ch;

    // 如果緩沖區(qū)已滿(mǎn)(達(dá)到128個(gè)字符)
    if (i == 128)
    {
        // 在緩沖區(qū)末尾添加結(jié)束符'\0',將其視為一個(gè)C風(fēng)格字符串添加到目標(biāo)string對(duì)象s中
        buff[i] = '\0';
        s += buff; // 更新s的內(nèi)容

        // 重置緩沖區(qū)索引為0,以便繼續(xù)填充下一個(gè)子字符串
        i = 0;
    }

    // 繼續(xù)從輸入流中獲取下一個(gè)字符
    ch = in.get();
}

// 若緩沖區(qū)中仍有剩余字符(循環(huán)結(jié)束后)
if (i != 0)
{
    // 添加結(jié)束符'\0',將剩余的子字符串添加到目標(biāo)string對(duì)象s中
    buff[i] = '\0';
    s += buff;
}

// 返回輸入流in的引用,以支持鏈?zhǔn)捷斎氩僮?    return in;
}

clear

不清理之前的數(shù)據(jù)就變成尾插了:

【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn),C++,c++,開(kāi)發(fā)語(yǔ)言,編程語(yǔ)言,函數(shù)的模擬實(shí)現(xiàn),C語(yǔ)言

void clear()
{
	_str[0] = '\0';
	_size = 0;
}

本篇結(jié)束。

??本文修改次數(shù):0

??更新時(shí)間:2024年4 月 24 日?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-860934.html

到了這里,關(guān)于【C++初階】第八站:string類(lèi)的模擬實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶(hù)投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【C++】string類(lèi)的模擬實(shí)現(xiàn)

    【C++】string類(lèi)的模擬實(shí)現(xiàn)

    前言:在上一篇中我們講到了string類(lèi)的使用方法,今天我們將進(jìn)一步的去學(xué)習(xí)string類(lèi),去底層看看它順帶模擬實(shí)現(xiàn)部分的內(nèi)容。 ?? 博主CSDN主頁(yè):衛(wèi)衛(wèi)衛(wèi)的個(gè)人主頁(yè) ?? ?? 專(zhuān)欄分類(lèi):高質(zhì)量C++學(xué)習(xí) ?? ??代碼倉(cāng)庫(kù):衛(wèi)衛(wèi)周大胖的學(xué)習(xí)日記?? ??關(guān)注博主和博主一起學(xué)習(xí)!一起努

    2024年03月21日
    瀏覽(23)
  • 【C++】String類(lèi)的模擬實(shí)現(xiàn)。

    ??博客主頁(yè):小智_x0___0x_ ??歡迎關(guān)注:??點(diǎn)贊??收藏??留言 ??系列專(zhuān)欄:C++初階 ??代碼倉(cāng)庫(kù):小智的代碼倉(cāng)庫(kù) string類(lèi)中需要三個(gè)成員變量分別記錄元素個(gè)數(shù)、容量和內(nèi)容。還需要一個(gè) size_t 類(lèi)型npos-1表示整型的最大值。 這段代碼是 string 類(lèi)的構(gòu)造函數(shù)。構(gòu)造函數(shù)是在

    2024年02月13日
    瀏覽(21)
  • C++ 之 string類(lèi)的模擬實(shí)現(xiàn)

    C++ 之 string類(lèi)的模擬實(shí)現(xiàn)

    這學(xué)習(xí)我有三不學(xué) 昨天不學(xué),因?yàn)樽蛱焓莻€(gè)過(guò)去 明天不學(xué),因?yàn)槊魈爝€是個(gè)未知數(shù) 今天不學(xué),因?yàn)槲覀円钤诋?dāng)下,我就是玩嘿嘿~ –?–?–?–?–?–?–?–?–?–?–?–?–?–?–?–?–?–?–?-正文開(kāi)始-?–?–?–?–?–?–?–?–?–?–

    2024年04月27日
    瀏覽(21)
  • 【c++】string類(lèi)的使用及模擬實(shí)現(xiàn)

    【c++】string類(lèi)的使用及模擬實(shí)現(xiàn)

    我們先了解一下什么是OOP思想 OOP思想,即面向?qū)ο缶幊蹋∣bject-Oriented Programming)的核心思想,主要包括“抽象”、“封裝”、“繼承”和“多態(tài)”四個(gè)方面。 抽象:抽象是忽略一個(gè)主題中與當(dāng)前目標(biāo)無(wú)關(guān)的那些方面,以便充分地注意與當(dāng)前目標(biāo)有關(guān)的方面。抽象并不打算了

    2024年04月11日
    瀏覽(24)
  • 【C++】——string類(lèi)的介紹及模擬實(shí)現(xiàn)

    【C++】——string類(lèi)的介紹及模擬實(shí)現(xiàn)

    C語(yǔ)言中,字符串是以’\\0’結(jié)尾的一些字符的集合,為了操作方便,C標(biāo)準(zhǔn)庫(kù)中提供了一些str系列的庫(kù)函數(shù),但是這些庫(kù)函數(shù)與字符串是分離開(kāi)的,不太符合OOP的思想,而且底層空間需要用戶(hù)自己管理,稍不留神可能還會(huì)越界訪問(wèn)。所以我們今天來(lái)學(xué)習(xí)C++標(biāo)準(zhǔn)庫(kù)中的string類(lèi)。

    2024年02月07日
    瀏覽(31)
  • STL中的string類(lèi)的模擬實(shí)現(xiàn)【C++】

    STL中的string類(lèi)的模擬實(shí)現(xiàn)【C++】

    構(gòu)造函數(shù)設(shè)置為缺省參數(shù),若不傳入?yún)?shù),則默認(rèn)構(gòu)造為空字符串。字符串的初始大小和容量均設(shè)置為傳入C字符串的長(zhǎng)度(不包括’\\0’) 在模擬實(shí)現(xiàn)拷貝構(gòu)造函數(shù)前,我們應(yīng)該首先了解深淺拷貝: 淺拷貝:拷貝出來(lái)的目標(biāo)對(duì)象的指針和源對(duì)象的指針指向的內(nèi)存空間是同一

    2024年02月15日
    瀏覽(22)
  • 【C++初階】模擬實(shí)現(xiàn)string的常見(jiàn)操作

    【C++初階】模擬實(shí)現(xiàn)string的常見(jiàn)操作

    ??個(gè)人主頁(yè):@Weraphael ???作者簡(jiǎn)介:目前學(xué)習(xí)C++和算法 ??專(zhuān)欄:C++航路 ?? 希望大家多多支持,咱一起進(jìn)步!?? 如果文章對(duì)你有幫助的話 歡迎 評(píng)論?? 點(diǎn)贊???? 收藏 ?? 加關(guān)注? 為了方便管理代碼,分兩個(gè)文件來(lái)寫(xiě): Test.cpp - 測(cè)試代碼邏輯 string.h - 模擬實(shí)現(xiàn) strin

    2024年02月12日
    瀏覽(33)
  • 【C++】深度剖析string類(lèi)的底層結(jié)構(gòu)及其模擬實(shí)現(xiàn)

    【C++】深度剖析string類(lèi)的底層結(jié)構(gòu)及其模擬實(shí)現(xiàn)

    在上兩篇中,我們已經(jīng)學(xué)習(xí)了string類(lèi)的一個(gè)使用,并且做了一些相關(guān)的OJ練習(xí),相信大家現(xiàn)在對(duì)于string的使用已經(jīng)沒(méi)什么問(wèn)題了。 那我們這篇文章呢,就來(lái)帶大家對(duì)string進(jìn)行一個(gè)模擬實(shí)現(xiàn),這篇文章過(guò)后,有些地方大家或許就可以理解的更深刻一點(diǎn)。 那通過(guò)之前文章的學(xué)習(xí)我

    2023年04月17日
    瀏覽(41)
  • 【C++練級(jí)之路】【Lv.6】【STL】string類(lèi)的模擬實(shí)現(xiàn)

    歡迎各位小伙伴關(guān)注我的專(zhuān)欄,和我一起系統(tǒng)學(xué)習(xí)C語(yǔ)言,共同探討和進(jìn)步哦! 學(xué)習(xí)專(zhuān)欄 : 《進(jìn)擊的C++》 關(guān)于 STL容器 的學(xué)習(xí),我會(huì)采用 模擬實(shí)現(xiàn) 的方式,以此來(lái)更加清楚地了解其 底層原理和整體架構(gòu) 。而string類(lèi)更是有100多個(gè)接口函數(shù),所以模擬實(shí)現(xiàn)的時(shí)候只會(huì)調(diào)重點(diǎn)和

    2024年01月18日
    瀏覽(30)
  • [C++] string類(lèi)的介紹與構(gòu)造的模擬實(shí)現(xiàn),進(jìn)來(lái)看吧,里面有空調(diào)

    [C++] string類(lèi)的介紹與構(gòu)造的模擬實(shí)現(xiàn),進(jìn)來(lái)看吧,里面有空調(diào)

    C語(yǔ)言中,字符串是以’\\0’結(jié)尾的一些字符的集合,為了操作方便,C標(biāo)準(zhǔn)庫(kù)中提供了一些str系列的庫(kù)函數(shù),但是這些庫(kù)函數(shù)與字符串是分離開(kāi)的,不太符合面向?qū)ο蟮乃枷?,而且底層空間需要用戶(hù)自己管理,稍不留神可能還會(huì)越界訪問(wèn)。 因此C++中,為了讓我們更簡(jiǎn)單、方便

    2024年02月12日
    瀏覽(19)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包