91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++?String部分成員怎么實現

發布時間:2022-08-29 16:56:16 來源:億速云 閱讀:94 作者:iii 欄目:開發技術

這篇文章主要介紹“C++ String部分成員怎么實現”,在日常操作中,相信很多人在C++ String部分成員怎么實現問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”C++ String部分成員怎么實現”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

string類的成員設計

	class string
	{
	private:
		char* _str;
		int _size;
		int _capacity;
	};

說明:以下的五個成員函數的模擬實現,均去除了_size_capacity成員變量,目的是為了更方便解釋重點。在五個成員函數模擬后,會對string類的設計進行補全。

普通構造函數的模擬

我們是否可以使用默認構造函數來初始化對象?在這種情況下是萬萬不能的!要記住默認的構造函數對自定義類型會去調用它自己的構造函數進行初始化,而對于內置類型是不做處理的,此時我們的成員變量_str的類型是內置類型,不會被初始化,所以一定要自己寫構造函數。

//這種構造函數是否可行?
string(const char* str)
{
	_str = str;
}

這種寫法做不到用字符串構造一個對象。

原因:這樣會使得str_str指向的都是同一塊空間。str會影響到_str.

C++?String部分成員怎么實現

所以正確的做法是,給_str分配一塊屬于自己的空間,再把str的值拷貝給_str.

string(const char* str)
{
	_str = new char[strlen(str) + 1]; //要多給一個'\0'的空間
	strcpy(_str, str);
}

C++?String部分成員怎么實現

修一下小細節:

1.實例化對象的時候是支持無參構造的,所以可以給參數一個缺省值"",里面自己隱藏的有一個\0.如果沒有傳參數,則使用缺省值。

string(const char* str = "")
{
	_str = new char[strlen(str) + 1]; //要多給一個'\0'的空間
	strcpy(_str, str);
}

拷貝構造函數的模擬

看了普通構造函數的模擬實現以后,最不應該犯的錯就是把一個string對象的數據直接給了另一個string對象

所以直接甩代碼

string(const string& s)
{
	_str = new char[strlen(s._str) + 1];
	strcpy(_str, s._str);
}

當然,如果有前面所寫普通構造函數,還可以利用普通構造函數來拷貝構造一個對象。

//還可以借助普通構造函數
string(const string& s)
	:_str(nullptr)
{
	string tmp(s._str);
	swap(_str, tmp._str);
}

賦值重載函數的模擬

這里重載賦值,是為了把一個已經存在的string對象的數據給另一個已經存在的string對象。

也就意味著,兩個對象均有自己的空間。不要把string對象的_str直接賦值,否則析構的時候會析構兩次,并且這兩個string對象由于_str使用的是同一塊空間,會相互之間影響。

string& operator=(const string& s)
{
	delete[] _str; //把原來的空間釋放掉
	_str = new char[strlen(s._str) + 1]; //給一塊新的空間
	strcpy(_str, s._str);;
}

上面這種方法是不行的。

1.不排除自己給自己賦值的情況,自己都給釋放了,拿什么來賦值?

2.使用delete先釋放,只要地址正確無論如何都會釋放成功,但是new一塊空間不一定會成功,如果一開始就給釋放了,而我去申請空間卻申請不到,那就是不僅沒有賦值成功,還把我自己原本有的給丟了。

//正確的寫法
string& operator=(const string& s)
{
	if (this != &s)
	{
		char* tmp = new char[strlen(s._str) + 1];
		strcpy(tmp, s._str);
		delete[] _str;
		_str = tmp;	
	}
	return *this; //如果自己給自己賦值,那就返回自己
}

還可以使用傳值的方法

string& operator=(string s)
{
	swap(_str, s._str);
	return *this;
}

C++?String部分成員怎么實現

String的析構函數模擬

~string()
{
	if (_str)
	{
		delete[] _str;
		_str = nullptr;
	}
}

補全上述的成員函數

//因為std庫里原本有一個string,所以這里加上一個命名空間,防止命名污染
namespace YDY
{
	class string
	{
	public:
		string(const char* str = "")
			:_size(strlen(str))
			,_capacity(_size)
		{
			_str = new char[_capacity + 1]; //要多給一個'\0'的空間
			strcpy(_str, str);
		}
		string(const string& s)
			:_str(nullptr)
			,_size(s._size)
			,_capacity(s._capacity)
		{
			string tmp(s._str);
			swap(_str, tmp._str);
		}
		string& operator=(const string& s)
		{
			if (this != &s)
			{
				char* tmp = new char[strlen(s._str) + 1];
				strcpy(tmp, s._str);
				delete[] _str;
				_str = tmp;
				_size = s._size;
				_capacity = s._capacity;
			}
			return *this;
		}
		~string()
		{
			if (_str)
			{
				delete[] _str;
				_str = nullptr;
			}
			_size = _capacity = 0;
		}
	private:
		char* _str;
		int _size;
		int _capacity;
	};
	void test()
	{
		string s1;
		string s2(s1);
		string s3 = s1;
	}
}

迭代器的簡單模擬

		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;
		}

其他成員函數的模擬

		const char* c_str()
		{
			return _str;
		}
		size_t size()
		{
			return _size;
		}
		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}
		const char& operator[](size_t pos) const
		{
			assert(pos < _size);
			return _str[pos];
		}
		//reserve
		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				//擴容到n+1
				//tmp是內置類型,
				char* tmp = new char[n + 1];
				strcpy(tmp, _str);
				delete[] _str;
				_str = tmp;

				_capacity = n;
			}
		}
		//
		void push_back(char c)
		{
			//空間不夠,擴容
			if (_size == _capacity)
			{
				//擴容
				reserve(_size + 1);
			}
			_str[_size] = c;
			_size++;
			_str[_size] = '\0';
		}
		void append(const char* str)
		{
			int len = strlen(str);
			if (_size + len > _capacity)
			{
				//增容
				reserve(_size + len);
			}
			strcpy(_str + _size, str);
			_size += len;
		}
		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}
		string& operator+=(const char* str)
		{
			//復用追加函數append()
			append(str);
			return *this;
		}
		//任意位置的插入
		string& insert(size_t pos, char ch)
		{
			if (_size == _capacity)
			{
				reserve(_size + 1);
			}
			//開始插入
			int end = _size + 1;
			//找到pos的位置,并留出pos的位置以便插入
			while (end > pos)
			{
				_str[end] = _str[end - 1];
				end--;
			}
			_str[pos] = ch;
			_size++;
			return *this;
		}
		string& insert(size_t pos, const char* str)
		{
			assert(pos < _size);
			size_t len = strlen(str);
			if (_size + len > _capacity)
			{
				//增容
				reserve(_size + len);
			}
			//找到pos的位置,并且留出要插入的位置
			size_t end = _size + len;
			while (end > pos)
			{
				_str[end] = _str[end - len];
				end--;
			}
			//開始插入
			strncpy(_str + pos, str, len);
			return *this;
		}
		//從pos的位置開始刪除len的長度
		string& erase(size_t pos = 0, size_t len = std::string::npos)
		{
			assert(pos < _size);
			if (len == std::string::npos || pos + len > _size)
			{
				_str[pos] = '\0';
				_size = pos;
			}
			else
			{
				strcpy(_str + pos, _str + pos + len);
				_size -= len;
			}
			return *this;
		}

到此,關于“C++ String部分成員怎么實現”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

始兴县| 库尔勒市| 宿州市| 二手房| 景宁| 光泽县| 行唐县| 汉中市| 临洮县| 灌云县| 仲巴县| 科技| 闽侯县| 江北区| 黎平县| 木里| 秀山| 青铜峡市| 葫芦岛市| 明光市| 涟源市| 綦江县| 会同县| 登封市| 武清区| 仁寿县| 陆丰市| 霍林郭勒市| 杨浦区| 呼和浩特市| 商南县| 南昌县| 凯里市| 佳木斯市| 文山县| 怀宁县| 酉阳| 海伦市| 揭西县| 岐山县| 桓仁|