上篇我们介绍了STL, STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,在C++的学习中,STL的学习是必不可少的。对于STL的学习,我们采用模拟实现——造轮子的方法来更好的了解和学习STL。在学习STL时,由于各个容器的接口众多,所以学会查看文档是很重要的,这里我们推荐一个 cplusplus网站来查看容器的相关接口。
string类介绍
string类本质是一个顺序表,用来存放字符,字符串,有了string我们就可以方便地对字符进行相关操作了。
string类文档介绍可以帮助我们更好学习( string在底层实际是:basic_string模板类的别名)。string类作为第一个容器(但cplusplus网站没有将其放入Containers中,单独列了一个string),接口有点繁杂,函数功能有点重复,只需掌握常用的即可。
总结
- string是表示字符串的字符串类。
- 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
- string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator>
string;- 不能操作多字节或者变长字符的序列。
使用时包含头文件string
string类函数接口总览
#pragma once
#include<iostream>
#include<assert.h>
#include<string>
using std:: cout;
using std:: cin;
using std:: endl;
using std:: ostream;
using std:: istream;
namespace djs
{
class string
{
public:
typedef char* iterator;
typedef const char* const_iterator;
static const size_t npos = -1;
//默认成员函数
string(const char* str = "");//常用
string(const string& str);//拷贝构造
~string();
string& operator= (const string& str);//赋值重载
//迭代器相关函数
iterator begin();//
const_iterator begin() const;//const对象并且只可读(const 对象本就不可改;返回值也应该不能改)
iterator end();
const_iterator end() const;
//容积相关函数
size_t size() const;
size_t capacity() const;
bool empty() const;
void reserve(size_t n = 0);
void resize(size_t n, char c='\0');//将库的二合一
//内容修改(增删)相关函数
string& insert(size_t pos, const char* s);
string& insert(size_t pos, char ch);//插入一个字符,库里没有该函数
void push_back(char c);
string& operator+= (const char* s);
string& operator+= (char c);
string& append(const char* s);
string& erase(size_t pos = 0, size_t len = npos);//全缺省,不指定删除区间则全部删除
void pop_back();
//字符串相关操作
const char* c_str() const;
void swap(string& str);
size_t find(const char* s, size_t pos = 0) const;
size_t find(char c, size_t pos = 0) const;
//访问
char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;
void clear();//不缩容
//比较关系运算符重载
bool operator>(const string& s)const;
bool operator>=(const string& s)const;
bool operator<(const string& s)const;
bool operator<=(const string& s)const;
bool operator==(const string& s)const;
bool operator!=(const string& s)const;
private:
char* _str;
size_t _capacity;
size_t _size;
};
//流出入和输出
ostream& operator<< (ostream& os, const string& str);
istream& operator>> (istream& is, string& str);
istream& getline(istream& is, string& str, char delim='\n');//改为默认以'\n'作为结束标志
}
为了不与库里的string冲突,我们将模拟实现的string放入自己的命名空间里。
结构介绍
string结构:
string类由于STL的版本不一样其结构(类成员)也有所不同。
VS下(PG版)的string的结构(了解):
注意:下述结构是在32位平台下进行验证,32位平台下指针占4个字节。
string总共占28个字节,内部结构稍微复杂一点,先是有一个联合体,联合体用来定义string中字符串的存储空间:
- 当字符串长度小于16时,使用内部固定的字符数组来存放。
- 当字符串长度大于等于16时,从堆上开辟空间。
union _Bxty
{
// storage for small buffer or pointer to larger one
value_type _Buf[_BUF_SIZE];
pointer _Ptr;
char _Alias[_BUF_SIZE]; // to permit aliasing
} _Bx;
这种设计也是有一定道理的,大多数情况下字符串的长度都小于16,那string对象创建好之后,内部已经有了16个字符数组的固定空间,不需要通过堆创建,效率高。
其次:还有一个size_t字段保存字符串长度,一个size_t字段保存从堆上开辟空间总的容量
最后:还有一个指针(不是_str)做一些其他事情。
故总共占16+4+4+4=28个字节。(x64平台下为40)
我们模拟实现的时候就不需要这么麻烦,因其本质为一个储存字符的舒徐