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

2021/5/2 20:27:16

本文主要是介绍C++学习笔记_14_string的底层原理及模拟实现,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

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

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


string简单用法 复习

目录

  • C++学习笔记_14_string的底层原理及模拟实现
  • 注:
  • 一、构造与析构
  • 二、常用功能
    • 1.遍历字符串并输出
    • 2.迭代器
  • 三、重载接口
    • 1. [ ]
    • 2. size()
    • 3. reserve
    • 4. push_back
    • 5. append
  • 四、重载拷贝构造
    • 其他


注:

为了不与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;
		}


这篇关于C++学习笔记_14_string的底层原理及模拟实现的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程