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

C++--string的模拟实现

一,引言

string的模拟实现是只对string对象中给的主要功能经行模拟实现,其目的是加强对string的底层了解,以便于在以后的学习或者工作中更加熟练的使用string。本文中的代码仅供参考并不唯一。

二,默认成员函数

string主要有三个成员变量,字符串指针--用于存放数据,size--记录有效数据,capacity--记录内存的大小。

1,构造函数

负责对成员变量进行初始化操作,当不传参数时,顺序表中只有\0用于表示顺序表的结束。当传入参数时,将传入的参数存入string对象中。具体实现如下:

string( const char* str = "")
{_str = new char[strlen(str) + 1];_size = strlen(str);_capacity = strlen(str);strcpy(_str, str);
}

在进行开辟空间时多开了一个字节的空间,该字节的空间负责存放\0。

分别是无参调用,和带参调用。

2,拷贝构造函数

负责实现对象的深拷贝。为构造函数的一种。具体实现如下:

string(string& str)
{_str = new char[str._capacity + 1];_size = str._size;_capacity = str._capacity;strcpy(_str, str._str);
}

初始化逻辑与实现原理基本相同。strcpy函数用于字符串复制,包含两个参数:第一个参数是目标地址,第二个参数是源地址。该函数会将源地址处直到'\0'结束符的所有字符(包括'\0')复制到目标地址所在位置。

将s1是由s2拷贝构造而来的。

3,析构函数

释放已开辟的内存空间并将指针置空,同时将相关参数清零,具体实现如下:

~string()
{delete[]_str;_str = nullptr;_size = _capacity = 0;
}

s1被析构。

4,赋值重载

重载赋值运算符(=),将源对象内容完整复制到目标对象,实现对象间的深度赋值。

三,其他成员函数

1,c_str

返回string对象的字符数组成员的首地址。 具体实现如下:

char* c_str()
{return this->_str;
}

2,size

返回string对象中有效数据的个数。具体实现如下:

size_t size()const
{return this->_size;
}

 

 3,capacity

返回string对象中的容量不包括\0。具体实现如下:

size_t capacity() const
{return this->_capacity;
}

 

4,[]运算符重载

实现string对象某个字符的修改。具体实现如下:

char& operator[](size_t pos)
{assert(pos < _size);return _str[pos];
}

返回的是该位置的引用可以对该对象的值进行修改。

对s1的第一个位置进行修改。

5,clear

清空对象内容,并将大小重置为0。具体实现如下:

void clear()
{_str[0] = '\0';_size = 0;
}

6.reserve

当对象内存不足时,该函数负责执行扩容操作。具体实现如下:

void string::reserve(size_t n)
{if (n > _capacity){int com = _capacity == 0 ? n : _capacity * 2;if(com < n){com = n;}char* ptr = new char[com + 1];strcpy(ptr, _str);delete[]_str;_str = ptr;ptr = nullptr;_capacity = com;}
}

当容量为零时,按需分配所需空间;若容量不为零,则比较当前需求与现有容量的两倍,取较大值以避免频繁扩容。注意,每次扩容时需额外预留一个字节用于存储字符串终止符'\0'。以下为测试用例演示:

int main()
{Cao::string s2("fdasjl");cout << s2.capacity() << endl;s2.reserve(10);cout << s2.capacity() << endl;Cao::string s1;cout << s1.capacity() << endl;s1.reserve(10);cout << s1.capacity() << endl;return 0;
}

7,push_back

尾插单个字符。具体实现如下:

void string::push_back(char ch)
{if (_size + 1 > _capacity){reserve(_size + 1);}_str[_size] = ch;_size++;_str[_size] = '\0';
}

 先判断容量了,再进行插入。

8,append

尾插字符串。具体实现如下:

void string::append(const char* str)
{if (_size + strlen(str) > _capacity){reserve(_size + strlen(str));}strcpy(_str + _size, str);_size = _size + strlen(str);}

先进行容量判断,之后插入。

9,insert

在指定位置插入字符串,具体实现如下:

void string::insert(size_t pos, const char* str)
{if (_size + strlen(str) > _capacity){reserve(_size + strlen(str));}strcpy(_str + pos + strlen(str), _str + pos);*this += str;_size += strlen(str);
}

先评估容量,再迁移数据腾出目标位置,最后插入字符串。

10,erase

指定位置,指定区域进行删除数据。具体实例如下:

void string::erase(size_t pos, size_t len )
{assert(pos < _size);if (pos + len >= _size){_str[pos] = '\0';_size = _size - pos;}else{strcpy(_str + pos, _str + pos + len);_size = _size - len;}
}

分为两种情况,第一种指定长度之后还存在数据。第二种情况是,指定长度之后没有数据。

11,find

查找字符串,找到之后返回首个字符的下标。没有找到返回npos。具体实现如下:

size_t string::find(const char* str, size_t pos )
{assert(pos < _size);{char* ptr = _str + pos;return  strstr(ptr, str) - _str ;}
}

 

四,总结

关于函数的具体功能,可以参考string这篇文章。在练习过程中,不必追求完美实现,重点在于理解string的底层代码逻辑及其使用方法。

相关文章:

  • docker相关(AI回答)
  • windows系统MySQL安装文档
  • Ubuntu Linux环境查看服务器资源,查询CPU,内存,环境变量等命令
  • 2023赣州旅游投资集团
  • 前端大文件分片上传详解 - Spring Boot 后端接口实现
  • Java多线程实现之Runnable接口深度解析
  • Redis专题-实战篇一-基于Session和Redis实现登录业务
  • 《射频识别(RFID)原理与应用》期末复习 RFID第三章 编码和调制(知识点总结+习题巩固)
  • 02__C++的基本语法
  • 【Linux系统】Linux环境变量:系统配置的隐形指挥官
  • [Java 基础]Object 类
  • IPC(进程间通信)详解
  • 升级背后:CANOPEN转MODBUS TCP技术如何实现精准控制?
  • Socket 编程
  • 【中间件】Web服务、消息队列、缓存与微服务治理:Nginx、Kafka、Redis、Nacos 详解
  • 认识电子元器件---高低边驱动
  • Day49 Python打卡训练营
  • IT供电系统绝缘监测及故障定位解决方案
  • 前端小程序面试题
  • SQL 注入:JDO与Hibernate
  • 怎么弄网站/优化模型数学建模
  • 网页设计与制作教程 刘瑞新/广东网络seo推广公司
  • 邢台做网站流程/如何设计推广方案
  • 平顶山哪里做网站/怎样做百度推广
  • 公司网站开发排名/口碑营销案例2021
  • 电子工程网官方网站/app推广拉新工作可靠吗