ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C++学习笔记_14_string的底层原理及模拟实现

2021-05-02 19:33:41  阅读:202  来源: 互联网

标签:capacity string C++ char str 14 const size


C++学习笔记_14_string的底层原理及模拟实现

在上节的学习,简单学习了string的用法,但只有了解底层原理并复现string部分代码才可以更好的理解和应用,我实现了string的部分功能。


string简单用法 复习

目录


注:

为了不与string.h文件重复(iostream中有时会包含,C++和Linux细节上有差别,暂时忽略),必须定义自己的命名空间,我的定义zgz(张公子)

namespace zgz
{}

在内部开始书写

一、构造与析构

要书写一个较为完整的string,首先分析string的构成:字符串、长度、空间大小
因此,对string的基本构造如下:

class string
	{
	public:
		string(const char* str = "")
			{
				_size = strlen(str);
				_capacity = _size;
				_str = new char[_capacity + 1];//  +1 是 \0
				strcpy(_str, str);
			}
			//对应的析构函数应该完成析构操作,并释放空间
		~string()
				{
					delete[] _str;
					_str = nullptr;//也可以没有这行
					_size = _capacity = 0;
				}
	private:
			char* _str;
			size_t _size;
			size_t _capacity;

二、常用功能

1.遍历字符串并输出

有了字符串,我们首先要完成的功能就是遍历并输出。
在Test.cpp中:
下面用到2种遍历,

int main()
{
	//1.for
	zgz::string s("abc1234");

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

	cout << endl;
	//2.迭代器
	zgz::string::iterator it = s.begin();
	
	//auto it = s.begin();
	while (it != s.end())
	{
		cout << *it << " ";
		++it;
	}
}

其中,原生指针就是天然的迭代器
输出结果为:
在这里插入图片描述

2.迭代器

迭代器写法如下:

//迭代器
		typedef char* iterator;
		
		iterator begin()
		{
			return _str;
		}

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

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

三、重载接口

此时,我们想到string的常用功能:

1. [ ]

2. size()

测试代码如下:
在这里插入图片描述
有明显的报错,这是因为没有重载这个功能。

实现如下:

char& operator[](size_t i)
	{
		assert(i < _size);//不能越界
		return _str[i];
	}

size_t size()
	{
		return _size;
	}

此时:
在这里插入图片描述

3. reserve

用来改变空间大小的:

void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n];
				strcpy(tmp, _str);
				delete[] _str;
				_str = tmp;
				_capacity = n;
			}
		}

当空间大小可以改变以后,就可以实现插入等操作了

4. push_back

void push_back(char ch)
		{
			if (_size == _capacity)
			{
				reserve(2 * _capacity);
			}
			_str[_size] = ch;
			++_size;
		}

5. append

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

			strcpy(_str + _size, str);
			_size += len;
		}

四、重载拷贝构造

有两种方式,分别是:s2(s1)和s3 = s1,整理思路,简单的拷贝构造有什么构造什么。
例如——string,需要构造str、capacity、size,但如果比较复杂,构造起来费时费力,那么采取新方法,让别人构造好,然后swap即可,具体实现如下:

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


		//s2(s1)
		string(const string& s)
			:_str(nullptr)
			, _capacity(0)
			, _size(0)
		{
			string tmp(s._str);
			swap(tmp);
		}

		//s3 = s1
		string& operator=(string s)
		{
			swap(s);
			return *this;
		}

其中的swap单纯为后面服务
测试代码:

zgz::string s2(s);
	for (size_t i = 0; i < s2.size(); i++)
	{
		cout << s2[i] ;
	}
	cout << endl;
	zgz::string s3 = s;
	for (size_t i = 0; i < s3.size(); i++)
	{
		cout << s3[i] ;
	}
	cout << endl;

结果如下:
在这里插入图片描述

其他

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

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

		string& operator+=(const string& s)
		{
			append(s._str);
			return *this;
		}

标签:capacity,string,C++,char,str,14,const,size
来源: https://blog.csdn.net/kris_paul/article/details/116277909

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有