您现在的位置是:首页 >技术杂谈 >C++ [STL之string模拟实现]网站首页技术杂谈
C++ [STL之string模拟实现]
简介C++ [STL之string模拟实现]
本文已收录至《C++语言和高级数据结构》专栏!
作者:ARMCSKGT
STL之string模拟实现
前言
前面我们介绍了STL容器string的部分接口使用,有了string使我们对字符串的操作如鱼得水,其实string不止于使用方便,其实现也有许多我们值得学习的地方,本节将为您介绍string常用接口的代码实现!
正文
本文接口的实现借助于C++官方文档,有需要请转阅:C++string官方文档
存储结构
string本质上是一个char类型的顺序表,实现起来与顺序表相似,所以结构上也相似!
namespace Mystring { class string { public: static const size_t npos; //全局比较变量 -1 private: //设置私有,不允许随便访问底层数据 char* _str; //字符串存储空间首地址指针 size_t _size; //当前字符数量 size_t _capaicty; //可用容量 } }
结构上使用命名空间Mystring进行封装,防止与库冲突,使用class封装成为对象string,其中:
- _str:指向字符串存放的空间的指针
- _size:代表当前所存储的有效字符数量
- _capacity:代表当前可存储的最大容量
- nops:此值设置为 -1,无符号整型转换就是42亿,且此值为const和静态参数具有全局效应,所以此值是public公开的,这个值常常被用来当作循环结束判断条件和查找时未找到的标志,某些函数设置其为缺省参数
其中许多整型变量的设定都为size_t无符号整型,但是关于nops,其定义为static const size_t,我们知道在类中定义static变量是在类外初始化的,但是如果该变量被const修饰则可以在类中进行初始化也可以在类外进行初始化,因为此变量的初始化只有一次;且const修饰的静态变量,只允许整型家族在类中设置缺省值(short,int,long,char等)!
所以在类中的static变量,没有被const修饰则需要严格在类外初始化,如果使用const修饰则可以在类中使用缺省参数的形式进行初始化也可以在类外初始化!
对于nops的初始化,以下方式都是可以的:class string { public: static const size_t npos = -1; }
class string { public: static const size_t npos; } const size_t string::nops = -1;
本次实现string采用声明与定义分离的方式实现,nops的定义和部分函数实现会在cpp文件中进行!
这里需要声明的是,因为是声明与定义分离实现,所以在CPP文件中包对应的头文件声明命名空间,然后通过 类名::成员(函数/变量) 定义和实现函数!
默认成员函数
我们知道类有六大成员函数,其中四个是常用的:
- 构造函数
- 拷贝构造函数
- 赋值重载
- 析构函数
至于剩下的取地址重载,使用默认生成的就够了!
对于这些成员函数和一些比较短小的函数我们可以在头文件类中直接实现,这样在某些场景下可以成为内联函数!
构造函数
构造函数用于初始化成员变量
在VS下string会多开一些空间且在对象创建时就会先开一部分空间,我们依照此特性进行设计!//构造函数 string(const char* s = "") //缺省参数默认构造空串 :_size(strlen(s)) { _capaicty = _size; _capaicty = _capaicty == 0 ? 4:_capaicty*(1.25); _str = new char[_capaicty + 1]; strcpy(_str, s); }
构造函数的思路如下:
- 构造函数接收一个字符串,默认的缺省参数为空串
- strlen先求出字符串长度并通过初始化列表初始化_size
- 通过判断_capacity计算需要的容量,如果0则是空串默认开4字节空间,否则计算字符串长度后多开1.25倍空间
- 容量确定后开空间,在此基础上多开一字节空间用于存放