欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

【C++】STL---string類(lèi)的模擬實(shí)現(xiàn)-創(chuàng)新互聯(lián)

目錄
  • 前言
  • 類(lèi)的屬性
  • 構(gòu)造函數(shù)
    • 構(gòu)造函數(shù)
    • 析構(gòu)函數(shù)
    • 拷貝構(gòu)造函數(shù)
  • 操作符重載
    • 賦值操作符重載
    • 比較操作符重載
  • 獲取字符串長(zhǎng)度
  • 下標(biāo)訪問(wèn)
  • 迭代器
  • 尾插一個(gè)字符
  • 追加字符串
  • 字符串清空
  • 字符串交換
  • 以C的方式返回字符
  • 判斷字符串是否為空
  • 修改長(zhǎng)度
  • 指定大小擴(kuò)容
  • 查找字符
  • 查找子串
  • 指定位置插入字符
  • 指定位置插入字符串
  • 刪除指定區(qū)間
  • 總結(jié):

創(chuàng)新互聯(lián)主營(yíng)門(mén)頭溝網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,手機(jī)APP定制開(kāi)發(fā),門(mén)頭溝h5成都小程序開(kāi)發(fā)搭建,門(mén)頭溝網(wǎng)站營(yíng)銷(xiāo)推廣歡迎門(mén)頭溝等地區(qū)企業(yè)咨詢前言

??string類(lèi),想必大家都不陌生,這是一個(gè)用來(lái)管理字符串的類(lèi)。讓我們使用字符串時(shí)更方便,更遍歷。所以今天我們就來(lái)簡(jiǎn)單的實(shí)現(xiàn)一下string類(lèi)。


類(lèi)的屬性

我們要管理一個(gè)字符串,那么首先得有一個(gè)字符串。所以我們用char* 類(lèi)型的指針,來(lái)指向一個(gè)塊存儲(chǔ)字符串的地址。_size則記錄字符串的長(zhǎng)度,_cacpcity 為字符串的空間容量

private:
		char* _str;
		size_t _size;
		size_t _cacpcity;
構(gòu)造函數(shù) 構(gòu)造函數(shù)

我們?cè)趯?shí)例化一個(gè)string對(duì)象的時(shí)候,可以string s("hello world");直接創(chuàng)建,也可以string s();使它初始時(shí)為空,所以我們可以用缺省的構(gòu)造函數(shù)。如果不傳參數(shù),那么默認(rèn)初始化為空。

//缺省的構(gòu)造函數(shù) 
		string(const char* str = "")
			: _size(strlen(str))
			,_cacpcity(_size)
		{	//開(kāi)辟一塊內(nèi)存
			_str = new char[_cacpcity + 1];//有效容量是cacpcity,要多一個(gè)用來(lái)存放\0
			strcpy(_str, str);
		}
析構(gòu)函數(shù)

析構(gòu)函數(shù)我們只需要釋放 _str指向的空間即可。

//析構(gòu)函數(shù)
		~string()
		{	delete[] _str;
			_str = nullptr;
			_size = _cacpcity = 0;
		}
拷貝構(gòu)造函數(shù)

拷貝構(gòu)造,就是拷貝一個(gè)字符串 例如:string s1("hello world"); string s2(s1);。所以我們開(kāi)辟一塊與要拷貝字符串一樣大小的空間,再把它一一復(fù)制給新字符串即可。

//拷貝構(gòu)造
		string(const string& s)
			:_size(s._size)
			, _cacpcity(s._cacpcity)
		{	//開(kāi)辟一塊和s一樣的空間
			_str = new char[_cacpcity+1];
			strcpy(_str, s._str);
		}
操作符重載 賦值操作符重載

如果我們想用 = 操作符來(lái)給字符串賦值。那我們可以重載 = 操作符。

//賦值操作符重載
		string& operator=(const string& s)
		{	//如果不是自己給自己賦值
			if (this != &s)
			{		//創(chuàng)建一塊新空間
				char* tmp = new char[s._cacpcity+1];
				//拷貝
				strcpy(tmp, s._str);
				//銷(xiāo)毀舊空間
				delete[] _str;
				_str = tmp;
				_size = s._size;
				_cacpcity = s._cacpcity;
			}
			return *this;
		}

當(dāng)然也可以復(fù)用拷貝構(gòu)造函數(shù)。

比較操作符重載

<重載

//字符串比較函數(shù)重載
		bool operator<(const string& s)
		{	return strcmp(_str, s._str)< 0;
		}

== 重載

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

<= 重載

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

? >重載

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

?>=重載

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

!=重載

bool operator!=(const string& s)
		{	return !(*this == s);
		}
獲取字符串長(zhǎng)度

直接返回_size 即可

//獲取長(zhǎng)度
		size_t size()
		{	return _size;
		}
下標(biāo)訪問(wèn)

字符串也可以進(jìn)行下標(biāo)訪問(wèn),所以我們重載[]即可

//下標(biāo)訪問(wèn)
		char& operator[](size_t pos)
		{	return _str[pos];
		}

當(dāng)然,如果訪問(wèn)的是const修飾的字符串,那我們只能讀,不能寫(xiě)。

//只讀
		const char& operator[](size_t pos) const
		{	return _str[pos];
		}
迭代器
//定義2個(gè)迭代器,一個(gè)是可讀可寫(xiě),一個(gè)是只讀
		typedef char* iterator;
		typedef const char* const_iterator;
//迭代器開(kāi)始位置
		iterator begin()
		{	return _str;
		}
		const_iterator begin() const
		{	return _str;
		}

		//迭代器末尾位置
		iterator end()
		{	return _str + _size;
		}

		const_iterator end()const
		{	return _str + _size;
		}
尾插一個(gè)字符

就是在字符串末端插入一個(gè)字符,我們只需要在_size的位置插入,隨后_size++即可。不過(guò)要保證容量必須充足。

//尾插一個(gè)字符
		void push_back(char c)
		{	//檢查容量
			if (_size == _cacpcity)
			{		AddCacpcity(_cacpcity == 0 ? 15 : _cacpcity * 2);
			}
			_str[_size] = c;
			_size++;
			_str[_size] = '\0';
		}

擴(kuò)容函數(shù)

void AddCacpcity(size_t newCacpcity)
		{		//末尾位置留一個(gè)\0,所以+1
				char* str = new char[newCacpcity + 1];
				//舊字符串的內(nèi)容拷貝到新字符串
				strcpy(str, _str);
				//銷(xiāo)毀舊字符串
				delete[] _str;
				_str = str;
				_cacpcity = newCacpcity;
		}
追加字符串

如果想在尾部追加字符串的話,我們可以實(shí)現(xiàn)一個(gè) append()函數(shù)。

//追加一個(gè)字符串
		void append(const char* str)
		{	//檢查容量
			if (_cacpcity< (_size)+strlen(str))
			{		AddCacpcity(_size + strlen(str));
			}
			//直接在末尾的位置加上str
			strcpy(_str + _size, str);
			_size += strlen(str);
		}

然后我們可以重載 +=運(yùn)算符,拿來(lái)復(fù)用 append()函數(shù)。

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

		}

然后我們重載 +運(yùn)算符,但需要注意的是,+運(yùn)算符不改變當(dāng)前字符串,所以我們要值返回。

//+重載
		string operator+(const char* str)
		{	string s(*this);
			s += str;

			return s;
		}
字符串清空

直接把第一個(gè)字符改成\0即可

//清空
		void clear()
		{	_str[0] = '\0';
			_size = 0;
		}
字符串交換

我們用std命名空間里面的swap函數(shù),對(duì)每個(gè)成員進(jìn)行交換。

//字符串交換
		void swap(string& s)
		{	std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_cacpcity, s._cacpcity);
		}
以C的方式返回字符

c語(yǔ)言的字符串其實(shí)就是一個(gè)char*指針,遇到\0結(jié)束,所以我們直接返回str就可以了。

//以c的方式返回字符串
		const char* c_str()const
		{	return _str;
		}
判斷字符串是否為空

直接判斷第一個(gè)元素是否是 \0

//判斷字符串是否為空
		bool empty()const
		{	return _str[0] == '\0';
		}
修改長(zhǎng)度

修改長(zhǎng)度我們要分多種情況,一般長(zhǎng)度減少時(shí),我們不改變現(xiàn)有容量。容量不夠時(shí),我們才增容。 如果 長(zhǎng)度減少,或者不變,我們只需要把 減少的新長(zhǎng)度給_size,然后把當(dāng)前位置變成\0。如果是增加長(zhǎng)度,我們要考慮容量,不夠的話需要增容,然后memset函數(shù)把增容的部分改成你指定的字符(默認(rèn)\0)。

//修改長(zhǎng)度
		void resize(size_t n, char c = '\0')
		{	//如果修改的值比當(dāng)前長(zhǎng)度小
			if (n<= _size)
			{		//截?cái)?				_size = n;
				_str[_size] = '\0';
			}
			//如果修改的值比當(dāng)前長(zhǎng)度大
			else
			{		//擴(kuò)容
				if(n >_cacpcity)
				{AddCacpcity(n);
				}
				//從size位置到n的位置設(shè)置為c
				memset(_str + _size, c, n - _size);
				//最后位置填上\0
				_size = n;
				_str[_size] = '\0';
			}
		}
指定大小擴(kuò)容

之前寫(xiě)過(guò)一個(gè)擴(kuò)容函數(shù),直接把指定的大小傳過(guò)去即可。還是老規(guī)矩,減少不處理。

//指定容量。只增加,減少不處理
		void reserve(size_t n)
		{	if (n >_cacpcity)
			{		AddCacpcity(n);
			}
		}
查找字符

該查找只會(huì)找到從指定位置開(kāi)始,第一個(gè)出現(xiàn)的字符。如果要查找第二個(gè),那么就在第一個(gè)字符的后面開(kāi)始查找。

// 返回c在string中第一次出現(xiàn)的位置
		size_t find(char c, size_t pos = 0) const
		{	for (int i = pos; i< _size; i++)
			{		if (_str[i] == c)
					return i;
			}
			
			return nops;
		}

nops是一個(gè)無(wú)符號(hào)的數(shù),代表找不到返回的值。

static const size_t nops = -1;
查找子串

C語(yǔ)言中有strstr函數(shù),我們可以復(fù)用。

// 返回子串s在string中第一次出現(xiàn)的位置
		size_t find(const char* s, size_t pos = 0) const
		{	char* tmp = strstr(_str, s);
			if (tmp == NULL)
				return nops;
			
			return tmp - _str;
		}
指定位置插入字符

只需要把pos位置后面的字符都往后移動(dòng)一格,隨后把字符放進(jìn)pos位置。

// 在pos位置上插入字符c/字符串str,并返回該字符的位置
		string& insert(size_t pos, char c)
		{	//判斷容量
			if (_size == _cacpcity)
			{		AddCacpcity(_cacpcity == 0 ? 15 : _cacpcity * 2);
			}
			//pos位置后往后移
			size_t end = _size + 1;
			while (pos< end)
			{		_str[end] = _str[end - 1];
				end--;
			}
			_str[pos] = c;
			_size++;

			return *this;
		}
指定位置插入字符串

插入字符是都往后移動(dòng)一格,插入字符串那就是把pos位置后面的字符都像后 移動(dòng)字符串的長(zhǎng)度格。然后把字符串從pos位置開(kāi)始寫(xiě)入。

//插入字符串
		string& insert(size_t pos, const char* str)
		{	size_t len = strlen(str);
			//判斷容量
			if (_cacpcity< (len + _size))
			{		AddCacpcity(len + _size);
			}
			//移動(dòng)len格
			size_t end1 = _size+1;
			size_t end2 = _size + len ;
			while (pos< end1 )
			{		_str[end2] = _str[end1-1]  ;
				end1--;
				end2--;
			}
			int i = pos;
			while (*str)
			{		 _str[i++] = *str++;
			}
			_size += len;
			return *this;
		}
刪除指定區(qū)間

從pos位置開(kāi)始,刪除len個(gè)空間。那么我們需要先判斷 len是否大于pos后面的長(zhǎng)度,如果大于那就是后面全部刪除,那么我們只需要把pos位置置空成\0即可。如果不大于就說(shuō)明在中間刪除,那么就從pos的第len個(gè)位置開(kāi)始往pos后面的位置覆蓋,覆蓋到\0結(jié)束。

// 刪除
		string& erase(size_t pos, size_t len)
		{	//如果要?jiǎng)h除的長(zhǎng)度大于后面的剩余長(zhǎng)度
			if (len >= _size - pos)
			{		len = _size - pos;
				_size -= len;
				_str[pos] = '\0';
				return *this;
			}
			//把后面的往前移,覆蓋式刪除
			size_t begin = pos+len;
			while (_str[begin])
			{		_str[begin-len] = _str[begin];
				begin++;
			}
			_size -= len;
			return *this;
		}
		

全部代碼:

namespace wyl
{class string
	{public:
		typedef char* iterator;
		typedef const char* const_iterator;
		//缺省的構(gòu)造函數(shù) 
		string(const char* str = "")
			: _size(strlen(str))
			,_cacpcity(_size)
		{	//開(kāi)辟一塊內(nèi)存
			_str = new char[_cacpcity + 1];
			strcpy(_str, str);
		}

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

		//拷貝構(gòu)造
		string(const string& s)
			:_size(s._size)
			, _cacpcity(s._cacpcity)
		{	//開(kāi)辟一塊和s一樣的空間
			_str = new char[_cacpcity+1];
			strcpy(_str, s._str);
		}

		//賦值操作符重載
		string& operator=(const string& s)
		{	//如果不是自己給自己賦值
			if (this != &s)
			{		//創(chuàng)建一塊新空間
				char* tmp = new char[s._cacpcity+1];
				//拷貝
				strcpy(tmp, s._str);
				//銷(xiāo)毀舊空間
				delete[] _str;
				_str = tmp;
				_size = s._size;
				_cacpcity = s._cacpcity;
			}
			return *this;
		}

		//獲取長(zhǎng)度
		size_t size()
		{	return _size;
		}
		
		//下標(biāo)訪問(wèn)
		char& operator[](size_t pos)
		{	return _str[pos];
		}
		//只讀
		const char& operator[](size_t pos) const
		{	return _str[pos];
		}

		//迭代器開(kāi)始位置
		iterator begin()
		{	return _str;
		}
		const_iterator begin() const
		{	return _str;
		}

		//迭代器末尾位置
		iterator end()
		{	return _str + _size;
		}

		const_iterator end()const
		{	return _str + _size;
		}

		// 擴(kuò)容
		void AddCacpcity(size_t newCacpcity)
		{		char* str = new char[newCacpcity + 1];
				strcpy(str, _str);
				delete[] _str;
				_str = str;
				_cacpcity = newCacpcity;
		}

		//尾插一個(gè)字符
		void push_back(char c)
		{	//檢查容量
			if (_size == _cacpcity)
			{		AddCacpcity(_cacpcity == 0 ? 15 : _cacpcity * 2);
			}
			_str[_size] = c;
			_size++;
			_str[_size] = '\0';
		}


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

		//追加一個(gè)字符串
		void append(const char* str)
		{	if (_cacpcity< (_size)+strlen(str))
			{		AddCacpcity(_size + strlen(str));
			}
			strcpy(_str + _size, str);
			_size += strlen(str);
		}

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

		}

		//+重載
		string operator+(const char* str)
		{	string s(*this);
			s += str;

			return s;
		}

		string operator+(const string& str)
		{	string s(*this);
			s += str._str;

			return s;
		}


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

		//字符串交換
		void swap(string& s)
		{	std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_cacpcity, s._cacpcity);
		}

		//以c的方式返回字符串
		const char* c_str()const
		{	return _str;
		}

		//判斷字符串是否為空
		bool empty()const
		{	return _str[0] == '\0';
		}

		//修改長(zhǎng)度
		void resize(size_t n, char c = '\0')
		{	//如果修改的值比當(dāng)前長(zhǎng)度小
			if (n<= _size)
			{		//截?cái)?				_size = n;
				_str[_size] = '\0';
			}
			//如果修改的值比當(dāng)前長(zhǎng)度大
			else
			{		//擴(kuò)容
				if(n >_cacpcity)
				{AddCacpcity(n);
				}
				//從size位置到n的位置設(shè)置為c
				memset(_str + _size, c, n - _size);
				//最后位置填上\0
				_size = n;
				_str[_size] = '\0';
			}
		}

		//指定容量。只增加,減少不處理
		void reserve(size_t n)
		{	if (n >_cacpcity)
			{		AddCacpcity(n);
			}
		}

		//字符串比較函數(shù)重載
		bool operator<(const string& s)
		{	return strcmp(_str, s._str)< 0;
		}

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

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

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

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

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

		// 返回c在string中第一次出現(xiàn)的位置
		size_t find(char c, size_t pos = 0) const
		{	for (int i = pos; i< _size; i++)
			{		if (_str[i] == c)
					return i;
			}
			
			return nops;
		}

		// 返回子串s在string中第一次出現(xiàn)的位置
		size_t find(const char* s, size_t pos = 0) const
		{	char* tmp = strstr(_str, s);
			if (tmp == NULL)
				return nops;
			
			return tmp - _str;
		}

		// 在pos位置上插入字符c/字符串str,并返回該字符的位置
		string& insert(size_t pos, char c)
		{	//判斷容量
			if (_size == _cacpcity)
			{		AddCacpcity(_cacpcity == 0 ? 15 : _cacpcity * 2);
			}
			//pos位置后往后移
			size_t end = _size + 1;
			while (pos< end)
			{		_str[end] = _str[end - 1];
				end--;
			}
			_str[pos] = c;
			_size++;

			return *this;
		}

		//插入字符串
		string& insert(size_t pos, const char* str)
		{	size_t len = strlen(str);
			//判斷容量
			if (_cacpcity< (len + _size))
			{		AddCacpcity(len + _size);
			}
			//移動(dòng)len格
			size_t end1 = _size+1;
			size_t end2 = _size + len ;
			while (pos< end1 )
			{		_str[end2] = _str[end1-1]  ;
				end1--;
				end2--;
			}
			int i = pos;
			while (*str)
			{		 _str[i++] = *str++;
			}
			_size += len;
			return *this;
		}



		// 刪除
		string& erase(size_t pos, size_t len)
		{	//如果要?jiǎng)h除的長(zhǎng)度大于后面的剩余長(zhǎng)度
			if (len >= _size - pos)
			{		len = _size - pos;
				_size -= len;
				_str[pos] = '\0';
				return *this;
			}
			//把后面的往前移,覆蓋式刪除
			size_t begin = pos+len;
			while (_str[begin])
			{		_str[begin-len] = _str[begin];
				begin++;
			}
			_size -= len;
			return *this;
		}
		

	private:
		char* _str;
		size_t _size;
		size_t _cacpcity;

		static const size_t nops = -1;

	};
}
總結(jié):

string類(lèi)的細(xì)節(jié)還有很多,在這里只能簡(jiǎn)單實(shí)現(xiàn)一下。在實(shí)現(xiàn)的過(guò)程中需要注意的幾點(diǎn)。

1.避免內(nèi)存越界,否則析構(gòu)時(shí)銷(xiāo)毀會(huì)出錯(cuò)。
2.釋放new出來(lái)的內(nèi)存,避免內(nèi)存泄漏。
3.需要深拷貝,否則會(huì)出現(xiàn)析構(gòu)多次的情況。

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)頁(yè)標(biāo)題:【C++】STL---string類(lèi)的模擬實(shí)現(xiàn)-創(chuàng)新互聯(lián)
網(wǎng)站地址:http://chinadenli.net/article14/hdgge.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、網(wǎng)站導(dǎo)航、Google、網(wǎng)站改版面包屑導(dǎo)航、企業(yè)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化