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库有更深的认知