【C++初阶】第10课—标准模板库STL(string的模拟实现)

发布于:2025-02-11 ⋅ 阅读:(34) ⋅ 点赞:(0)

模拟实现string类

  • 注意:函数声明和函数定义分离时,只能在函数声明、定义选其一给缺省值
  • 类中的成员函数声明和定义分离时,定义需要指定类域,以便于编译器识别是哪个类域的成员函数

1 string的默认构造和析构

在这里插入图片描述


//string的默认构造
string(const char* str = "")
	:_size(strlen(str))
{
	_capacity = _size;
	_str = new char[_size + 1];
	strcpy(_str, str);
}

//c类字符串
const char* c_str() const
{
	return _str;
}

//string的析构
~string()
{
	delete[] _str;
}

2 string的增删改查(追加字符/字符串)

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述


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

//尾插字符
void string::push_back(char ch)
{
	//扩容
	if (_size == _capacity)
	{
		reserve(_capacity == 0 ? 4 : 2 * _capacity);
	}
	//尾插
	_str[_size++] = ch;
	_str[_size] = '\0';
}

//追加字符串
void string::append(const char* s)
{
	size_t len = strlen(s);
	//扩容
	if (2 * _capacity > _size + len && _size + len > _capacity)
	{
		reserve(_capacity == 0 ? 4 : 2 * _capacity);
	}
	else if (_size + len > 2 * _capacity)
	{
		reserve(_size + len);
	}
	//尾插
	strcpy(_str + _size, s);
	_size += len;
}
//运算符重载+=字符
string& string::operator+=(const char ch)
{
	push_back(ch);
	return *this;
}

//运算符重载+=字符串
string& string::operator+=(const char* str)
{
	append(str);
	return *this;
}

3 string类的增删改查(insert插入字符/字符串)

在这里插入图片描述


在这里插入图片描述


//insert插入字符
void string::insert(size_t pos, size_t n, char c)
{
	assert(pos <= _size);
	assert(n > 0);
	size_t len = n;
	//扩容
	if (_size + len >= _capacity && _size + len < 2 * _capacity)
	{
		reserve(_capacity == 0 ? 4 : 2 * _capacity);
	}
	else if (_size + len > 2 * _capacity)
	{
		reserve(_size + len + 1);
	}
	//挪动数据
	for (size_t i = _size + len; i >= pos + len; i--)
	{
		_str[i] = _str[i - len];
	}
	//插入数据
	for (size_t j = pos; j < pos + len; j++)
	{
		_str[j] = c;
	}
	_size += len;
}

//insert插入字符串
void string::insert(size_t pos, const char* str)
{
	assert(pos >= 0 && pos <= _size);
	size_t len = strlen(str);
	//扩容
	if (_size + len >= _capacity && _size + len < 2 * _capacity)
	{
		reserve(_capacity == 0 ? 4 : 2 * _capacity);
	}
	else if (_size + len > 2 * _capacity)
	{
		reserve(_size + len + 1);
	}
	//挪动数据
	for (size_t i = _size + len; i >= pos + len; i--)
	{
		_str[i] = _str[i - len];
	}
	//插入字符串
	for (size_t j = 0; j < len; j++)
	{
		_str[pos + j] = str[j];
	}
	_size += len;
}

4 erase删除pos位置len个字符

在这里插入图片描述


在这里插入图片描述


5 find查找字符/字符串

在这里插入图片描述


6 有效字符、容量、[ ]下标访问、迭代器

  • 这里对迭代器的实现采用指针的形式
//有效字符
size_t size() const
{
	return _size;
}

//容量
size_t capacity() const
{
	return _capacity;
}

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

//迭代器const版本
typedef const char* const_iterator;
const_iterator begin() const
{
	return _str;
}
const_iterator end() const
{
	return _str + _size;
}
//重载下标访问操作符[]
char& string::operator[](size_t pos)
{
	assert(pos < _size);
	return _str[pos];
}
//重载下标访问操作符[]---const版本
const char& string::operator[](size_t pos) const
{
	assert(pos < _size);
	return _str[pos];
}

7 subsur取string子串和赋值运算符重载

在这里插入图片描述


在这里插入图片描述


8 判断运算符重载

//判断运算符重载
bool string::operator==(const string& s) const
{
	return strcmp(this->_str, s._str) == 0;
}
bool string::operator!=(const string& s) const
{
	return !(*this == s);
}
bool string::operator>(const string& s) const
{
	return strcmp(_str, s._str) > 0;
}
bool string::operator<(const string& s) const
{ 
	return !(*this > s || *this == s);
}
bool string::operator>=(const string& s) const
{
	return !(*this < s);
}
bool string::operator<=(const string& s) const
{
	return !(*this > s);
}

9 流插入和流提取

在这里插入图片描述


  • 以上关于流提取函数没有任何问题,但是流插入函数在每次插入字符时都需要去扩容,频繁扩容占用资源

在这里插入图片描述


10 getline读取一行字符串

在这里插入图片描述


11 再探string的拷贝构造

在这里插入图片描述


在这里插入图片描述


  • 浅拷贝存在两个问题:一是它会多次析构,二是变量的改变会影响其他对象
  • 解决办法:一是使用深拷贝;二是使用引用计数的写时拷贝
  • 这里主要了解引用计数的写时拷贝

在这里插入图片描述


12 编码

  • 统一码(Unicode),也叫万国码、单一码,由统一码联盟开发,是计算机科学领域里的一项业界标准,包括字符集、编码方案等
  • 在统一码中,汉字“字”对应的数字是23383。在统一码中,我们有很多方式将数字23383表示成程序中的数据,包括:UTF-8、UTF-16、UTF-32三种编码.UTF是“UCS Transformation Format”的缩写,可以翻译成统一码字符集转换格式,即怎样将统一码定义的数字转换成程序数据。
  • UTF-8编码中,它是以一个字节为单位,通常汉字采用该编码形式时,一个汉字用2个字节编写
  • 类似的,UTF-16和UTF-32则分别以2个字节、4个字节为单位编码
  • string又属于basic_string,它使用的编码形式就是UTF-8的编码

在这里插入图片描述


在这里插入图片描述


13 字符串和整数、浮点数转换

  • 参考,需要时查阅官方文档

在这里插入图片描述



网站公告

今日签到

点亮在社区的每一天
去签到