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

【C++】String類的模擬實現(xiàn)。

這篇具有很好參考價值的文章主要介紹了【C++】String類的模擬實現(xiàn)。。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

??博客主頁:小智_x0___0x_

??歡迎關注:??點贊??收藏??留言

??系列專欄:C++初階

??代碼倉庫:小智的代碼倉庫

模擬實現(xiàn)

成員變量

string類中需要三個成員變量分別記錄元素個數(shù)、容量和內(nèi)容。還需要一個size_t類型npos-1表示整型的最大值。

private:
		size_t _size;//個數(shù)
		size_t _capacity;//容量
		char* _str;//字符數(shù)組
public:
		const static size_t npos;
const size_t string::npos = -1;//npos代表的整型的最大值。

構造函數(shù)

//構造函數(shù)
string(const char* str = "")
{
	_size = strlen(str);
	_capacity = _size;
	_str = new char[_capacity + 1];
	memcpy(_str, str, _size + 1);
}

這段代碼是string類的構造函數(shù)。構造函數(shù)是在創(chuàng)建對象時自動調(diào)用的函數(shù),用于初始化對象的數(shù)據(jù)成員。
這個構造函數(shù)接受一個const char*類型的參數(shù)str,默認值為一個空字符串。
在函數(shù)體內(nèi),首先使用strlen函數(shù)獲取參數(shù)str的長度,并將其賦值給私有成員變量_size,表示字符串的個數(shù)。
接著,將_capacity的值初始化為_size,表示容量與個數(shù)相等。
然后,使用new運算符動態(tài)分配一個大小為_capacity + 1的字符數(shù)組,并將指針賦值給私有成員變量_str。
最后,使用memcpy函數(shù)將參數(shù)str中的字符串復制到新分配的字符數(shù)組中,并在最后一個位置設置為\0,表示字符串的結束。
因此,這個構造函數(shù)的作用是將一個C風格的字符串轉換為string對象。

析構函數(shù)

//析構函數(shù)
~string()
{
	delete[] _str;
	_str = nullptr;
	_size = _capacity = 0;
}

這段代碼是string類的析構函數(shù)。析構函數(shù)是在對象被銷毀時自動調(diào)用的函數(shù),用于釋放對象占用的資源。
在函數(shù)體內(nèi),首先使用delete[]運算符釋放_str指向的動態(tài)分配的字符數(shù)組。
然后,將_str賦值為nullptr,表示指針不再指向任何內(nèi)存地址。
最后,將_size_capacity的值都設為0,表示對象已經(jīng)被銷毀。
因此,這個析構函數(shù)的作用是釋放string對象占用的內(nèi)存空間,并將對象的數(shù)據(jù)成員重置為初始值。

拷貝構造

//拷貝構造
string(const string& str)
{
	_str = new char[str._capacity + 1];
	memcpy(_str, str._str, str._size + 1);
	_size = str._size;
	_capacity = str._capacity;
}

這段代碼是string類的拷貝構造函數(shù)??截悩嬙旌瘮?shù)是在創(chuàng)建一個新對象并用已有對象進行初始化時自動調(diào)用的函數(shù),用于將一個對象的值復制到另一個對象中。
這個拷貝構造函數(shù)接受一個const string&類型的引用參數(shù)str,表示要被復制的對象。
在函數(shù)體內(nèi),首先使用new運算符動態(tài)分配一個大小為str._capacity + 1的字符數(shù)組,并將指針賦值給私有成員變量_str。
然后,使用memcpy函數(shù)將參數(shù)str中的字符串復制到新分配的字符數(shù)組中,并在最后一個位置設置為\0,表示字符串的結束。
接著,將_size_capacity的值分別賦值為參數(shù)str對應的私有成員變量值,表示新對象的大小和容量與原對象相同。
因此,這個拷貝構造函數(shù)的作用是創(chuàng)建一個新的string對象,并將參數(shù)str中的數(shù)據(jù)成員值復制到新對象中。

c_str()

//返回C語言類型的字符串
const char* c_str() const
{
	return _str;
}

這段代碼是string類的c_str函數(shù),用于返回一個指向以空字符結尾的字符數(shù)組的指針,該字符數(shù)組包含了當前string對象中存儲的字符串。
這個函數(shù)沒有參數(shù),返回值為const char*類型。
在函數(shù)體內(nèi),直接返回私有成員變量_str,該變量是一個指向字符數(shù)組的指針,指向當前string對象中存儲的字符串。
由于返回值是一個指向常量字符的指針,因此該函數(shù)被聲明為const類型成員函數(shù),表示該函數(shù)不會修改對象的數(shù)據(jù)成員。
因此,這個函數(shù)的作用是返回當前string對象中存儲的字符串的C語言類型表示。

size()

//返回長度
size_t size() const
{
	return _size;
}

這段代碼是string類的size函數(shù),用于返回當前string對象中存儲的字符串的長度,即字符的個數(shù)。
這個函數(shù)沒有參數(shù),返回值為size_t類型。
在函數(shù)體內(nèi),直接返回私有成員變量_size,該變量表示當前string對象中存儲的字符串的長度。
由于該函數(shù)不會修改對象的數(shù)據(jù)成員,因此被聲明為const類型成員函數(shù)。
因此,這個函數(shù)的作用是返回當前string對象中存儲的字符串的長度。

重載[]運算符

//重載[]運算符
char& operator[](size_t pos)
{
	assert(pos < _size);
	return _str[pos];
}
const char& operator[](size_t pos) const
{
	assert(pos < _size);
		
	return _str[pos];
}

這段代碼是string類對[]運算符進行重載的實現(xiàn)。通過重載[]運算符,可以使用類似數(shù)組下標的方式訪問和修改string對象中的字符。
這個代碼片段包含了兩個重載版本,一個是非常量版本,另一個是常量版本。
在非常量版本中,重載的[]運算符接受一個size_t類型的參數(shù)pos,表示要訪問或修改的字符的索引位置。
在函數(shù)體內(nèi),首先使用assert函數(shù)來檢查索引位置是否越界,即是否小于字符串的長度_size。
然后,返回私有成員變量_str中索引位置為pos的字符的引用,以便可以修改該字符的值。
在常量版本中,重載的[]運算符也接受一個size_t類型的參數(shù)pos
在函數(shù)體內(nèi),同樣使用assert函數(shù)來檢查索引位置是否越界。
然后,返回私有成員變量_str中索引位置為pos的字符的常量引用,以保證該字符的值不會被修改。
因此,這段代碼的作用是重載string類的[]運算符,使得可以通過下標訪問和修改字符串中的字符。

擴容函數(shù)

reserve()

//擴容函數(shù)
void reserve(size_t n)
{
	if (n > _capacity)
	{
		char* tmp = new char[n + 1];
		memcpy(tmp, _str, _size+1);
		delete[] _str;
		_str = tmp;
		_capacity = n;
	}
}

這段代碼是string類的reserve函數(shù),用于增加當前string對象的容量,以便可以存儲更多的字符。
這個函數(shù)接受一個size_t類型的參數(shù)n,表示要增加的容量大小。
在函數(shù)體內(nèi),首先判斷參數(shù)n是否大于當前對象的容量_capacity。如果是,則需要進行擴容操作。
在擴容操作中,首先使用new運算符動態(tài)分配一個大小為n+1的字符數(shù)組,并將指針賦值給臨時變量tmp。
然后,使用memcpy函數(shù)將當前對象中的字符串復制到新分配的字符數(shù)組中,這個函數(shù)比strcpy更快,因為不需要在找到\0之后繼續(xù)復制。
接著,使用delete[]運算符釋放當前對象中原來的字符數(shù)組。
最后,將指向新分配的字符數(shù)組的指針賦值給私有成員變量_str,表示當前對象已經(jīng)擴容。同時,將私有成員變量_capacity的值更新為新的容量大小。
因此,這個函數(shù)的作用是增加當前string對象的容量,以便可以存儲更多的字符。

resize()

void resize(size_t n, char ch = '\0')
{
	if (n < _size)
	{
		_size = n;
		_str[_size] = '\0';
	}
	else
	{
		reserve(n);
		for (size_t i = _size; i < n; i++)
		{
			_str[i] = ch;
		}
		_size = n;
		_str[_size] = '\0';
	}
}

這段代碼是string類的resize函數(shù),用于改變當前string對象中存儲的字符串的長度。
這個函數(shù)接受一個size_t類型的參數(shù)n,表示要改變的字符串長度。同時,還接受一個可選的char類型參數(shù)ch,表示在擴展字符串時要填充的字符,默認值為\0。
在函數(shù)體內(nèi),首先判斷參數(shù)n是否小于當前對象中存儲的字符串的長度_size。如果是,則需要縮小字符串的長度。
在縮小字符串長度的操作中,首先將私有成員變量_size的值更新為n,表示當前對象中存儲的字符串的長度已經(jīng)縮小到了n。
然后,在新的字符串長度之后添加一個空字符\0,以便可以正確地表示新的字符串。
如果參數(shù)n大于等于當前對象中存儲的字符串的長度_size,則需要擴展字符串的長度。
在擴展字符串長度的操作中,首先調(diào)用成員函數(shù)reserve(n)來確保當前對象中分配的內(nèi)存空間足夠存儲新的字符串。
然后,在當前對象中存儲的字符串的末尾添加字符ch,直到新字符串的長度達到了n。
最后,將私有成員變量_size的值更新為n,表示當前對象中存儲的字符串的長度已經(jīng)擴展到了n。同時,在新字符串長度之后添加一個空字符\0,以便可以正確地表示新的字符串。
因此,這個函數(shù)的作用是改變當前string對象中存儲的字符串的長度,并根據(jù)需要在新字符串中添加或刪除字符。

尾插

push_back()

//push_back()
void push_back(char ch)
{
	if (_size == _capacity)
	{
		reserve(_capacity == 0 ? 4 : 2 * _capacity);
	}
	_str[_size] = ch;
	++_size;
	_str[_size] = '\0';
}

這段代碼是string類的push_back函數(shù),用于向當前string對象中添加一個字符。
這個函數(shù)接受一個char類型的參數(shù)ch,表示要添加的字符。
在函數(shù)體內(nèi),首先判斷當前對象中存儲的字符串的長度_size是否等于當前對象的容量_capacity。如果是,則需要進行擴容操作。
在擴容操作中,調(diào)用成員函數(shù)reserve(_capacity == 0 ? 4 : 2 * _capacity)來增加當前對象的容量。如果當前對象的容量為0,則增加容量到4;否則,將容量增加到原來的2倍。
然后,在私有成員變量_str中索引位置為_size的位置添加字符ch,表示將該字符添加到當前對象的末尾。
接著,將私有成員變量_size的值加1,表示當前對象中存儲的字符串的長度已經(jīng)增加了1個字符。
最后,在新字符串長度之后添加一個空字符\0,以便可以正確地表示新的字符串。
因此,這個函數(shù)的作用是向當前string對象中添加一個字符,并在需要時自動擴容以確保有足夠的空間存儲該字符。

append()

void append(const char* str)
{
	size_t len = strlen(str);
	if (len + _size > _capacity)
	{
		reserve(len + _size);
	}
	memcpy(_str + _size, str, len + 1);
	_size += len;
}

這段代碼是string類的append函數(shù),用于將一個以空字符結尾的C字符串附加到當前string對象中。
這個函數(shù)接受一個const char*類型的參數(shù)str,表示要附加的C字符串。
在函數(shù)體內(nèi),首先使用strlen函數(shù)計算出C字符串的長度,并將其存儲在臨時變量len中。
然后,判斷將要附加的C字符串的長度加上當前對象中存儲的字符串的長度是否大于等于當前對象的容量。如果是,則需要進行擴容操作。
在擴容操作中,調(diào)用成員函數(shù)reserve(len + _size)來增加當前對象的容量,以確保有足夠的空間存儲將要附加的C字符串。
接著,使用memcpy函數(shù)將C字符串復制到當前對象中存儲的字符串的末尾。這個函數(shù)比strcpy更快,因為不需要在找到\0之后繼續(xù)復制。
最后,將私有成員變量_size的值增加C字符串的長度len,表示當前對象中存儲的字符串的長度已經(jīng)增加了C字符串的長度。
因此,這個函數(shù)的作用是將一個以空字符結尾的C字符串附加到當前string對象中,并在需要時自動擴容以確保有足夠的空間存儲該字符串。

重載+=運算符

//重載+=運算符
string& operator+=(char ch)
{
	push_back(ch);
	return *this;
}
string& operator+=(const char* str)
{
	append(str);
	return *this;
}

這里都是都是復用了上面的push_back()和append()

插入函數(shù)insert

插入字符

//在指定位置插入n個字符
void insert(size_t pos, size_t n, char ch)
{
	assert(pos <= _size);
	if (_size + n > _capacity)
	{
		reserve(_size + n);
	}
	size_t end = _size;
	while (end >= pos && end != npos)//npos整型最大值
	{
		_str[end + n] = _str[end];
		--end;
	}
	for (size_t i = pos; i < pos + n; i++)
	{
		_str[i] = ch;
	}
	_size += n;
}

這段代碼是string類的insert函數(shù),用于在當前string對象中的指定位置插入指定數(shù)量的字符。
這個函數(shù)接受三個參數(shù):一個size_t類型的參數(shù)pos,表示要插入字符的位置;一個size_t類型的參數(shù)n,表示要插入的字符數(shù)量;一個char類型的參數(shù)ch,表示要插入的字符。
在函數(shù)體內(nèi),首先使用assert函數(shù)檢查要插入的位置是否在當前對象中存儲的字符串的范圍內(nèi)。如果不在范圍內(nèi),則程序會終止。
然后,判斷將要插入的字符數(shù)量加上當前對象中存儲的字符串的長度是否大于等于當前對象的容量。如果是,則需要進行擴容操作。
在擴容操作中,調(diào)用成員函數(shù)reserve(_size + n)來增加當前對象的容量,以確保有足夠的空間存儲將要插入的字符。
接著,從當前對象中存儲的字符串的末尾開始,將每個字符向后移動n個位置。這個操作是為了給將要插入的字符騰出空間。
然后,在指定位置插入n個字符。這個操作使用了一個for循環(huán),從pos開始,循環(huán)n次,每次將要插入的字符添加到當前對象中存儲的字符串中。
最后,將私有成員變量_size的值增加n,表示當前對象中存儲的字符串的長度已經(jīng)增加了n個字符。
需要注意的是,在while循環(huán)中使用了變量npos,這個變量是一個常量,表示無效的位置。在這個函數(shù)中,它被用來表示當前對象中存儲的字符串已經(jīng)被遍歷完了。
因此,這個函數(shù)的作用是在當前string對象中指定位置插入指定數(shù)量的字符,并在需要時自動擴容以確保有足夠的空間存儲這些字符。

插入字符串

//在指定位置插入一個字符串
void insert(size_t pos, const char* str)
{
	assert(pos <= _size);
	size_t len = strlen(str);
	if (_size + len > _capacity)
	{
		reserve(_size + len);
	}
	size_t end = _size;
	while (end >= pos && end != npos)//npos表示整型最大值
	{
		_str[end + len] = _str[end];
		--end;
	}
	for (size_t i = pos; i < pos + len; i++)
	{
		_str[i] = str[i - pos];
	}
	_size += len;
}

這段代碼是string類的insert函數(shù),用于在當前string對象中的指定位置插入一個C風格字符串。
該函數(shù)首先檢查要插入的位置是否在當前對象中存儲的字符串的范圍內(nèi),然后計算要插入的字符串長度。如果將要插入的字符數(shù)量加上當前對象中存儲的字符串的長度大于等于當前對象的容量,則需要進行擴容操作。
在擴容操作中,調(diào)用成員函數(shù)reserve(_size + len)來增加當前對象的容量,以確保有足夠的空間存儲將要插入的字符串。
接著,從當前對象中存儲的字符串的末尾開始,將每個字符向后移動len個位置。這個操作是為了給將要插入的字符串騰出空間。
然后,在指定位置插入字符串。這個操作使用了一個for循環(huán),從pos開始,循環(huán)len次,每次將要插入的字符添加到當前對象中存儲的字符串中。
最后,將私有成員變量_size的值增加len,表示當前對象中存儲的字符串的長度已經(jīng)增加了len個字符。

erase

//指定位置刪除n個字符
void erase(size_t pos, size_t len = npos)
{
	assert(pos <= _size);
	if (len == npos || pos + len >= _size)
	{
		_str[pos] = '\0';
		_size = pos;
		_str[_size] = '\0';
	}
	else
	{
		size_t end = pos + len;
		while (end <= _size)
		{
			_str[pos++] = _str[end++];
		}
		_size -= len;
	}
}

這段代碼是string類的erase函數(shù),用于從當前string對象中的指定位置開始刪除指定數(shù)量的字符。
這個函數(shù)接受兩個參數(shù):一個size_t類型的參數(shù)pos,表示要刪除字符的起始位置;一個size_t類型的參數(shù)len,表示要刪除的字符數(shù)量,其默認值為npos,表示刪除從起始位置到當前對象末尾的所有字符。
在函數(shù)體內(nèi),首先使用assert函數(shù)檢查要刪除的位置是否在當前對象中存儲的字符串的范圍內(nèi)。如果不在范圍內(nèi),則程序會終止。
然后,判斷要刪除的字符數(shù)量是否等于npos或者要刪除的字符數(shù)量加上要刪除的起始位置是否大于等于當前對象中存儲的字符串的長度。如果是,則將當前對象中存儲的字符串從指定位置開始到末尾的所有字符都刪除,并將當前對象中存儲的字符串的長度更新為指定位置。
否則,從指定位置開始,將要刪除的字符向后移動len個位置。這個操作使用了一個while循環(huán),從pos開始,循環(huán)到pos+len結束,每次將要刪除的字符向后移動一個位置。
最后,將私有成員變量_size的值減去len,表示當前對象中存儲的字符串的長度已經(jīng)減少了len個字符。
需要注意的是,在if語句中,將pos位置處的字符設置為’\0’,是為了在刪除操作后保證當前對象中存儲的字符串以’\0’結尾。

查找函數(shù)find

查找字符

//在指定位置查找一個字符
size_t find(char ch, size_t pos = 0)
{
	assert(pos < _size);
	for (size_t i = pos; i < _size; i++)
	{
		if (_str[i] == ch)
		{
			return i;
		}
	}
	return npos;
}

這段代碼是string類的find函數(shù),用于在當前string對象中的指定位置開始查找一個字符。
這個函數(shù)接受兩個參數(shù):一個char類型的參數(shù)ch,表示要查找的字符;一個size_t類型的參數(shù)pos,表示從哪個位置開始查找,其默認值為0。
在函數(shù)體內(nèi),首先使用assert函數(shù)檢查要查找的起始位置是否在當前對象中存儲的字符串的范圍內(nèi)。如果不在范圍內(nèi),則程序會終止。
然后,使用一個for循環(huán)從指定位置開始遍歷當前對象中存儲的字符串。如果遍歷到的字符等于要查找的字符,則返回該字符在當前對象中存儲的字符串中的位置。
如果整個字符串都被遍歷完了,還沒有找到要查找的字符,則返回常量npos,表示未找到。
需要注意的是,在這個函數(shù)中,變量npos表示整型最大值,被用來表示未找到要查找的字符。

查找字符串

//在指定位置查找一個字符串
size_t find(const char* str, size_t pos = 0)
{
	assert(pos < _size);
	const char* ptr = strstr(_str + pos, str);
	if (ptr)
	{
		return ptr - _str;
	}
	else
	{
		return npos;
	}
}

這段代碼是string類的find函數(shù),用于在當前string對象中的指定位置開始查找一個字符串。
這個函數(shù)接受兩個參數(shù):一個const char*類型的參數(shù)str,表示要查找的字符串;一個size_t類型的參數(shù)pos,表示從哪個位置開始查找,其默認值為0。
在函數(shù)體內(nèi),首先使用assert函數(shù)檢查要查找的起始位置是否在當前對象中存儲的字符串的范圍內(nèi)。如果不在范圍內(nèi),則程序會終止。
然后,使用C標準庫函數(shù)strstr在當前對象中存儲的字符串中查找要查找的字符串。這個函數(shù)返回一個指向第一次出現(xiàn)要查找的字符串的指針,如果沒找到則返回NULL
如果找到了要查找的字符串,則返回該字符串在當前對象中存儲的字符串中的位置。由于strstr函數(shù)返回的是指向要查找的字符串在當前對象中存儲的字符串中的位置的指針,因此需要將這個指針減去當前對象中存儲的字符串的首地址,才能得到該字符串在當前對象中存儲的字符串中的位置。
如果整個字符串都被遍歷完了,還沒有找到要查找的字符串,則返回常量npos,表示未找到。
需要注意的是,在這個函數(shù)中,變量npos表示整型最大值,被用來表示未找到要查找的字符串。

substr()

//截取一段字符串
string substr(size_t pos = 0, size_t len = npos)
{
	assert(pos < _size);
	size_t n = len;
	if (len == npos || pos + len > _size)
	{
		n = _size - pos;
	}
	string tmp;
	tmp.reserve(n);
	for (size_t i = pos; i < pos + n; i++)
	{
		tmp += _str[i];
	}
		return tmp;
}

這段代碼是string類的substr函數(shù),用于從當前string對象中的指定位置開始獲取一個子字符串。
這個函數(shù)接受兩個參數(shù):一個size_t類型的參數(shù)pos,表示子字符串的起始位置,其默認值為0;一個size_t類型的參數(shù)len,表示子字符串的長度,其默認值為npos,表示獲取從起始位置到當前對象末尾的所有字符。
在函數(shù)體內(nèi),首先使用assert函數(shù)檢查要獲取子字符串的起始位置是否在當前對象中存儲的字符串的范圍內(nèi)。如果不在范圍內(nèi),則程序會終止。
然后,判斷要獲取的子字符串的長度是否等于npos或者要獲取的子字符串的長度加上要獲取的子字符串的起始位置是否大于當前對象中存儲的字符串的長度。如果是,則將要獲取子字符串的長度設置為從指定位置開始到當前對象末尾的所有字符的長度。
接著,創(chuàng)建一個臨時的string對象tmp,并使用reserve函數(shù)為這個對象分配足夠的內(nèi)存空間。這個內(nèi)存空間大小為要獲取子字符串的長度。
最后,使用一個for循環(huán)從指定位置開始,將要獲取的子字符串中的每個字符添加到臨時的string對象中。循環(huán)結束后,返回臨時的string對象。
需要注意的是,在這個函數(shù)中,變量npos表示整型最大值,被用來表示要獲取從起始位置到當前對象末尾的所有字符。

重載<運算符

bool operator<(const string& s) const
{
	int ret = memcmp(_str, s._str, _size < s._size ? _size : s._size);			
	return ret == 0 ? _size < s._size : ret < 0;
}

這段代碼是string類的小于運算符重載函數(shù),用于比較當前string對象和另一個string對象的大小關系。
這個函數(shù)接受一個const string&類型的參數(shù)s,表示要比較的另一個string對象。
在函數(shù)體內(nèi),使用C標準庫函數(shù)memcmp比較當前對象中存儲的字符串和另一個對象中存儲的字符串的前綴部分,比較的長度為兩個字符串中長度更短的那個。返回值為0表示兩個字符串相等,返回值小于0表示當前對象中存儲的字符串小于另一個對象中存儲的字符串,返回值大于0表示當前對象中存儲的字符串大于另一個對象中存儲的字符串。
然后,使用三目運算符判斷兩個字符串是否相等。如果相等,則比較兩個字符串的長度,返回長度更短的那個字符串小于另一個字符串。如果不相等,則返回比較結果。
需要注意的是,在這個函數(shù)中,使用了C標準庫函數(shù)memcmp來進行字符串的比較,而不是使用循環(huán)遍歷比較每個字符。這是因為memcmp函數(shù)可以利用CPU的特殊指令集進行優(yōu)化,從而提高比較效率。

重載==運算符

bool operator==(const string& s) const
{
	return _size == s._size
		&& memcmp(_str, s._str, _size) == 0;
}

這段代碼是string類的等于運算符重載函數(shù),用于比較當前string對象和另一個string對象是否相等。
這個函數(shù)接受一個const string&類型的參數(shù)s,表示要比較的另一個string對象。
在函數(shù)體內(nèi),首先比較當前對象中存儲的字符串的長度和另一個對象中存儲的字符串的長度是否相等,如果不相等,則直接返回false,表示兩個對象不相等。
然后,使用C標準庫函數(shù)memcmp比較當前對象中存儲的字符串和另一個對象中存儲的字符串是否相等。比較的長度為兩個字符串中長度更短的那個。返回值為0表示兩個字符串相等,返回值不為0表示兩個字符串不相等。
最后,使用邏輯運算符&&將前面兩個比較的結果合并起來,如果兩個比較都為真,則返回true,表示兩個對象相等;否則返回false,表示兩個對象不相等。

重載<=、>、>=、!=運算符

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);
}
bool operator!=(const string& s) const
{
	return !(*this == s);
}

上面這些代碼也都是復用了'>'和'=='的代碼。

string中的swap函數(shù)

void swap(string& s)
{
	std::swap(_str, s._str);
	std::swap(_size, s._size);
	std::swap(_capacity, s._capacity);
}

這段代碼是string類的swap函數(shù),用于交換當前string對象和另一個string對象的內(nèi)容。
這個函數(shù)接受一個string&類型的參數(shù)s,表示要交換內(nèi)容的另一個string對象。
在函數(shù)體內(nèi),使用C++標準庫函數(shù)std::swap來交換當前對象中存儲的字符串和另一個對象中存儲的字符串、當前對象中存儲的字符串的長度和另一個對象中存儲的字符串的長度、當前對象中存儲的字符串的容量和另一個對象中存儲的字符串的容量。

重載=運算符

第一種重載方法

string& operator=(const string& s)
{
	if (this != &s)
	{
		char* tmp = new char[s._capacity + 1];
		memcpy(tmp, s._str, s._size+1);
		delete[] _str;
		_str = tmp;
		_size = s._size;
		_capacity = s._capacity;
	}
	return *this;
}

第二種重載方法

string& operator=(const string& s)
{
	if (this != &s)
	{
		string tmp(s);
		swap(tmp);
	}
	return *this;
}

第三種重載方法

string& operator=(string tmp)
{
	swap(tmp);
	return *this;
}

迭代器

typedef char* iterator;
typedef const char* const_iterator;
iterator begin()
{
	return _str;
}
iterator end()
{
	return _str + _size;
}
const_iterator begin() const
{
	return _str;
}
const_iterator end() const
{
	return _str + _size;
}

這段代碼是string類的迭代器相關函數(shù),用于提供對string對象中存儲的字符串字符的訪問。
在這個代碼中,首先使用typedef關鍵字定義了兩個類型別名iteratorconst_iterator,分別表示可變迭代器和不可變迭代器。可變迭代器可以用于修改string對象中存儲的字符串,而不可變迭代器則不能。
然后,定義了兩個函數(shù)begin()end(),分別返回可變迭代器和不可變迭代器。這兩個函數(shù)用于返回一個指向當前對象中存儲的字符串的首字符的指針和一個指向當前對象中存儲的字符串的尾字符的下一個字符的指針。

流插入

ostream& operator<<(ostream& out, const string& s)
{
for (auto ch : s)
{
	out << ch;
}
	return out;
}

這段代碼是string類的輸出運算符重載函數(shù),用于將當前string對象的內(nèi)容輸出到輸出流中。
這個函數(shù)接受一個ostream&類型的參數(shù)out,表示要輸出到的輸出流,以及一個const string&類型的參數(shù)s,表示要輸出的string對象。
在函數(shù)體內(nèi),使用C++11中的范圍for循環(huán)遍歷當前對象中存儲的字符串中的每個字符。對于每個字符,使用輸出運算符<<將其輸出到輸出流中。
最后,返回輸出流的引用。

流提取

istream& operator>>(istream& in, string& s)
{
	s.clear();
	char ch = in.get();
	// 處理前緩沖區(qū)前面的空格或者換行
	while (ch == ' ' || ch == '\n')
	{
		ch = in.get();
	}
	char buff[128];
	int i = 0;
	while (ch != ' ' && ch != '\n')
	{
		buff[i++] = ch;
		if (i == 127)
		{
			buff[i] = '\0';
			s += buff;
			i = 0;
		}
		ch = in.get();
	}
	if (i != 0)
	{
		buff[i] = '\0';
		s += buff;
	}
	return in;
}

這段代碼是一個重載了輸入流操作符(>>)的函數(shù),用于從輸入流中讀取字符串數(shù)據(jù)。:

  1. 首先,函數(shù)會清空字符串 s,以確保其為空。
  2. 接下來,使用 in.get() 函數(shù)讀取輸入流中的一個字符,并將其賦值給變量 ch
  3. 在一個循環(huán)中,檢查字符 ch 是否是空格或換行符。如果是,則繼續(xù)調(diào)用 in.get() 讀取下一個字符,直到遇到非空格和非換行符的字符為止,這樣可以跳過輸入流中前面的空格或換行。
  4. 創(chuàng)建一個字符數(shù)組 buff,起初為空。然后,在另一個循環(huán)中,將非空格和非換行符的字符存入 buff 中,并逐個增加索引 i。
  5. 檢查索引 i 是否達到了上限(127),即是否已經(jīng)存滿了 buff 數(shù)組。如果是,將 buff 數(shù)組最后一個字符設置為字符串結束符(‘\0’),并將其內(nèi)容添加到字符串 s 的末尾。然后,重置索引 i 為0。
  6. 繼續(xù)執(zhí)行循環(huán),直到遇到空格或換行符。在每次循環(huán)迭代時,將非空格和非換行符的字符存入 buff 中,并逐個增加索引 i。
  7. 最后,檢查索引 i 是否不為0,即是否有未添加到字符串 s 的字符。如果是,將 buff 數(shù)組最后一個字符設置為字符串結束符(‘\0’),并將其內(nèi)容添加到字符串 s 的末尾。
  8. 返回輸入流 in,以支持鏈式輸入操作。
    總體來說,該代碼通過循環(huán)讀取輸入流中的字符,并根據(jù)空格和換行符的位置將字符拼接成一個字符串。這樣,使用該函數(shù)可以便捷地從輸入流中讀取一個帶有空格或換行符分隔的字符串。

??小結??

今天我們認識了C++string類的模擬實現(xiàn)相信大家看完有一定的收獲。
種一棵樹的最好時間是十年前,其次是現(xiàn)在! 把握好當下,合理利用時間努力奮斗,相信大家一定會實現(xiàn)自己的目標!加油!創(chuàng)作不易,辛苦各位小伙伴們動動小手,三連一波????~~~,本文中也有不足之處,歡迎各位隨時私信點評指正!
本節(jié)課的代碼已上傳gitee倉庫文章來源地址http://www.zghlxwxcb.cn/news/detail-547412.html

到了這里,關于【C++】String類的模擬實現(xiàn)。的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

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

領支付寶紅包贊助服務器費用

相關文章

  • 【C++】String類的模擬實現(xiàn)。

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

    2024年02月13日
    瀏覽(20)
  • 【C++】string類的模擬實現(xiàn)

    【C++】string類的模擬實現(xiàn)

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

    2024年03月21日
    瀏覽(22)
  • C++ 之 string類的模擬實現(xiàn)

    C++ 之 string類的模擬實現(xiàn)

    這學習我有三不學 昨天不學,因為昨天是個過去 明天不學,因為明天還是個未知數(shù) 今天不學,因為我們要活在當下,我就是玩嘿嘿~ –?–?–?–?–?–?–?–?–?–?–?–?–?–?–?–?–?–?–?-正文開始-?–?–?–?–?–?–?–?–?–?–

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

    【c++】string類的使用及模擬實現(xiàn)

    我們先了解一下什么是OOP思想 OOP思想,即面向對象編程(Object-Oriented Programming)的核心思想,主要包括“抽象”、“封裝”、“繼承”和“多態(tài)”四個方面。 抽象:抽象是忽略一個主題中與當前目標無關的那些方面,以便充分地注意與當前目標有關的方面。抽象并不打算了

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

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

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

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

    STL中的string類的模擬實現(xiàn)【C++】

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

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

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

    ??個人主頁:@Weraphael ???作者簡介:目前學習C++和算法 ??專欄:C++航路 ?? 希望大家多多支持,咱一起進步!?? 如果文章對你有幫助的話 歡迎 評論?? 點贊???? 收藏 ?? 加關注? 為了方便管理代碼,分兩個文件來寫: Test.cpp - 測試代碼邏輯 string.h - 模擬實現(xiàn) strin

    2024年02月12日
    瀏覽(33)
  • 【C++】深度剖析string類的底層結構及其模擬實現(xiàn)

    【C++】深度剖析string類的底層結構及其模擬實現(xiàn)

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

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

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

    2024年01月18日
    瀏覽(30)
  • [C++] string類的介紹與構造的模擬實現(xiàn),進來看吧,里面有空調(diào)

    [C++] string類的介紹與構造的模擬實現(xiàn),進來看吧,里面有空調(diào)

    C語言中,字符串是以’\\0’結尾的一些字符的集合,為了操作方便,C標準庫中提供了一些str系列的庫函數(shù),但是這些庫函數(shù)與字符串是分離開的,不太符合面向對象的思想,而且底層空間需要用戶自己管理,稍不留神可能還會越界訪問。 因此C++中,為了讓我們更簡單、方便

    2024年02月12日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

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

二維碼1

領取紅包

二維碼2

領紅包