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

C++之string类的实现代码及其详解(上)

1. 什么是string类

在 C++ 中,string 是标准库(<string>)提供的类,用于表示和操作字符串。它是对传统 C 风格字符数组(char[])的封装,提供了更安全、便捷的字符串操作功能,如动态内存管理、长度自动跟踪和丰富的成员函数。

同时我们设计了一些接口函数来实现对他的调用。

PS:string在调用的时候只要加头文件含#include头文件以及using namespace std即可。

2. string本身代码实现

我们先把string本身实现一下,然后在它的代码上再添加接口函数。

我们来看下面这个代码,我们先把char*和const char*重命名为iterator和const_iterator是因为这样写更加规范(也显得更加专业)。

class string{public:typedef char* iterator;typedef const char* const_iterator;}

2.1 begin与end

首先我们在private创建了三个成员函数,_str:指向动态分配的字符数组(以 \0 结尾的 C 风格字符串),_size:当前字符串的有效字符长度(不包含终止符)和_capacity:当前分配的内存空间大小(包含终止符位置)。接下来我们实现了普通版本的begin,end和const版本的begin和end。这里我们要理解在const版本的begin和end后面的那个const是指向this指针的。

class string{public:typedef char* iterator;typedef const char* const_iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}const_iterator begin() const{return _str;}const_iterator end() const{return _str + _size;}private:size_t _size;size_t _capacity;char* _str;};

2.2 构造函数

然后我们通过构造函数来实现对string的初始化,在这里我们写成const char* str = ""是为了允许无参调用构造函数,创建空字符串对象(因为不能说初始化为空就直接报错)。我们在capacity后面加2是为了给 \0 留位置同时防止越界访问,同时我们在这里是使用memcpy是为了直接复制指定字节数,这样不容易出现错误。注意我们把str给_str是为了实现初始化的时候赋值,比如说string a1("aaaaaaaaaa")这样。

class string{public:typedef char* iterator;typedef const char* const_iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}const_iterator begin() const{return _str;}const_iterator end() const{return _str + _size;}string(const char* str = ""){_size = strlen(str);_capacity = _size;_str = new char[_capacity + 2];memcpy(_str, str, _size+1);}private:size_t _size;size_t _capacity;char* _str;};
}

PS:在这里_str是一个指向数组开头元素的指针。

2.3 拷贝构造函数

首先拷贝构造都是传引用返回(为了防止套娃,即递归触发拷贝构造函数)。然后我们给_str开传进来的s.capacity+2个空间,

class string{public:typedef char* iterator;typedef const char* const_iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}const_iterator begin() const{return _str;}const_iterator end() const{return _str + _size;}string(const char* str = ""){_size = strlen(str);_capacity = _size;_str = new char[_capacity + 2];memcpy(_str, str, _size+1);}string(const string& s){_str = new char[s._capacity + 2];memcpy(_str, s._str,s._size+1);_size = s._size;_capacity = s._capacity;}private:size_t _size;size_t _capacity;char* _str;};
}

PS:各位有没有想过为什么在这里s就可以直接使用capacity呢,为什么在构造函数里面不可以这样,而是要通过strlen呢?简单来说就是因为str是外部传入的,而s是内部类对象所以可以互相访问。

2.4 析构函数

首先我们通过delete来对_str里面的内容进行清理,接着把_str数组置为空(这一步是为了防止出现野指针现象),最后我们把_size和_capacity都置为空。

class string{public:typedef char* iterator;typedef const char* const_iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}const_iterator begin() const{return _str;}const_iterator end() const{return _str + _size;}string(const char* str = ""){_size = strlen(str);_capacity = _size;_str = new char[_capacity + 2];memcpy(_str, str, _size+1);}string(const string& s){_str = new char[s._capacity + 2];memcpy(_str, s._str,s._size+1);_size = s._size;_capacity = s._capacity;}~string(){delete[]_str;_str = nullptr;_size = _capacity = 0;}private:size_t _size;size_t _capacity;char* _str;};

相关文章:

  • 0 数学习题本
  • 【stm32】HAL库开发——Cube配置基本定时器
  • Llama 3 + Qwen2双模型实战:单张3090构建企业级多模态知识库(2025精解版)
  • 关于 ARM64 汇编:调用流程与栈帧结构解析
  • Jenkins与Kubernetes深度整合实践
  • GitLab 18.1 高级 SAST 已支持 PHP,可升级体验!
  • OSPF 路由协议详细笔记
  • Python-7-读取/写入文件数据
  • mb_bootloop_le.elf是使用microblaze默认的elf文件,这个文件包括哪些内容?
  • n8n智能体新境界:MCP服务器简化复杂自动化
  • Apache 支持 HTTPS
  • 系统性能优化-6 TCP 三次握手
  • easyExcel导入多sheet的Excel,存在合并单元格、列不固定的情况
  • 自动获取文件的内存大小怎么设置?批量获取文件名和内存大小到Excel中的方法
  • notepad++ 怎么快速给 python (nginx、shell) 文件加 # 注释
  • 远程玩3A大作要多少帧?ToDesk、向日葵、UU远程性能对决
  • 从零搭建高效本地代理池:设计与实现
  • Ubuntu中控制用户cpu资源分配控制步骤
  • Flutter 多平台项目开发指南
  • 【Go语言-Day 9】指针基础:深入理解内存地址与值传递