当前位置: 首页 > article >正文

C++详细笔记(七)(string底层初步实现)

1.string库简介

C++ 的string库提供了std::string类型,用于方便地处理文本字符串。它是 C++ 标准模板库(STL)的一部分,相比于 C 语言中以'\0'结尾的字符数组(C - 风格字符串),std::string提供了更安全、高效和便捷的字符串操作方式。

2.string库实现

string实现

string底层相当于顺序表,按着顺序存储字符。所以最开始的声明我们可以使用顺序表来声明

#include <iostream>
using namespace std;
namespace Dai
{
	class string
	{
private:
	size_t _size;//字符串的字符个数
	size_t _capacity;//该顺序表所开辟出的空间
	char* _str;//字符串的首元素地址
    };
}
string(const char* str ="");
~string();

string::string(const char* str )
	:_size(strlen(str))
{
	_str = new char[_size + 1];
	_capacity = _size;
	strcpy(_str, str);
}
string::~string()
{
	delete[]_str;//确保delete[]与之前通过new[]分配的内存严格配对使用
	_capacity = 0;
	_size = 0;
}

string的拷贝构造和析构函数,其中有前文中讲到的初始化列表,以及_size+1是给‘\0’留的空间。

拷贝构造深挖

string::string(const string& s)//全手动复制拷贝
{
_str = new char[s._capacity + 1];
strcpy(_str, s._str);
_capacity = s._capacity;
_size = s._size;
}
void string::swap(string& s)//半自动化
{
	std::swap(_str, s._str);
	std::swap(_capacity, s._capacity);
	std::swap(_size, s._size);
}
string::string(const string& s)//全自动化
{
	string tmp(s._str);
	swap(tmp);
}

由三段代码比较看出,第一段是由我们自己赋值,开空间。第二段为我们调用swap函数来提我们赋值,开空间。而第三段利用了临时对象和swap函数来避免直接逐个字符地复制源对象的数据到目标对象。

其中STL库中迭代器是一个很重要的东西,虽然string可以直接用下表遍历,但string始终是一个特例,而迭代器是所有库中都适用的

迭代器

typedef char* iterator;

iterator begin();
iterator end();
iterator rbegin();
iterator rend();
iterator cbegin() const;
iterator cend() const;

string::iterator string::begin()
{
	return _str;
}
string::iterator string::end()
{
	return _str + _size;
}
string::iterator string::rbegin()
{
	return _str + _size;
}
string::iterator string::rend()
{
	return _str;
}
string::iterator string::cbegin()const
{
	return _str;
}
string::iterator string::cend()const
{
	return _str + _size;
}

迭代器的使用

以下两种均为迭代器(iterator)的使用

#include <iostream>
#include <string>
int main() {
    std::string str = "Hello";
    std::string::iterator it_begin = str.begin();
    std::string::iterator it_end = str.end();
    for (std::string::iterator it = it_begin; it!= it_end; ++it) {
        std::cout << *it;
    }
    std::cout << std::endl;
    return 0;
}

#include <iostream>
#include <string>
int main() {
    const std::string str = "World";
    for (auto it = str.cbegin(); it!= str.cend(); ++it) {
        std::cout << *it;
    }
    std::cout << std::endl;
    return 0;
}

无需返回值的函数

void swap(string& s);
void clear();
void replace(size_t n,size_t m,const string &s);
void reserve(int n);
void append(const string&s,int n,int m);
void assign(const string& s);


void string::clear()
{
	delete[]_str;
	_size = 0;
	_capacity = 0;
}

		void string::replace(size_t n, size_t m,const string& s)
		{
			for (int i = n; i < m; i++)
			{
				_str[i] = s._str[i];
				_size = s._size;
				_capacity = s._capacity;

			}
		}
		void string::reserve(int n)
		{
			_str = new char[n + 5];
			_capacity = n + 5;
		}
		void string::append(const string& s, int n, int m)
		{
			if (s._str > _str)
			{
				_str = s._str;
				for (int i = n; i < m; i++)
				{
					_str[i] = _str[i];
				}
				_capacity = s._capacity;
				_size = s._size;
			}
			else
			{
				for (int i = n; i < m; i++)
				{
					_str[i] = _str[i];
				}
				_capacity = s._capacity;
				_size = s._size;
			}
		}
		void string::assign(const string& s)
		{
			string::clear();
			strcpy(_str, s._str);
			_capacity = s._capacity;
			_size = s._size;
		}
		size_t string::find(char n)
		{
			int cout = 0;
			for (int i = 0; i < _size; i++)
			{
				if (_str[i] == n)
				{
					return cout;
				}
				cout++;
			}
		}
}

需返回值的函数

size_t size();
size_t lenght();
size_t capacity();
size_t find(char n);
size_t campare(const string& s);
size_t campare(size_t n, size_t m, const string& s);

size_t string::size()
{
	return _size;
}
size_t string::capacity()
{
	return _capacity;
}
size_t string::lenght()
{
	return _size;
}

size_t string::campare(const string& s)
{
	int ret = 0;
	for (int i = 0; i < _size; i++)
	{
		ret= _str[i] - s._str[i];
	}
	return ret;
}
size_t string::campare(size_t n, size_t m, const string& s)
{
	int ret = 0;
	for (int i = n; i < m; i++)
	{
		ret = _str[i] - s._str[i];
	}
	return ret;
}
size_t string::find(char n)
{
	int cout = 0;
	for (int i = 0; i < _size; i++)
	{
		if (_str[i] == n)
		{
			return cout;
		}
		cout++;
	}
}

这些函数对应上一章节的C++详细笔记(六)中的部分函数进行大致实现以实现部分功能来对string库有更深的认知


http://www.kler.cn/a/408357.html

相关文章:

  • Android 不同情况下使用 runOnUiThread
  • Elasticsearch客户端在和集群连接时,如何选择特定的节点执行请求的?
  • 1992-2021年 各省市县经过矫正的夜间灯光数据(GNLD、VIIRS)区域汇总:省份、城市、区县面板数据
  • leetcode 919.完全二叉树插入器
  • 【数据结构】归并排序 —— 递归及非递归解决归并排序
  • 2024 APMCM亚太数学建模C题 - 宠物行业及相关产业的发展分析和策略 完整参考论文(1)
  • 曲谱转换成音频
  • 【免费】高比例风电电力系统储能运行及配置分析【火电机组、风能、储能】
  • 企业数智化新纪元,安全体系保驾护航
  • 蓝桥杯嵌入式再学习(4)led的点亮
  • 淘宝接口高并发采集优化之道:提升数据获取速度与质量
  • RTOS学习笔记---任务的管理
  • jsencrypt 库作用
  • 【设计模式系列】责任链模式(十六)
  • Jedis存储一个以byte[]的形式的对象到Redis
  • 模型压缩——如何进行知识蒸馏?
  • kotlin 的循环
  • 【MySQL】开发技术深度探索:mysql数据库复合查询全面详解
  • Group Convolution(分组卷积)
  • 1123--collection接口,list接口,set接口
  • scau编译原理综合性实验
  • 【数据结构】链表重难点突破
  • CTF之密码学(键盘加密)
  • Linux(2)
  • 16.C++STL 3(string类的模拟,深浅拷贝问题)
  • 〔 MySQL 〕中三种重要的日志类型