标准类库中的string 类以及其模拟实现
string类:
什么是string类:
- 字符串是表示字符序列的类 。
- 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作 单字节字符字符串的设计特性。
- string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信 息,请参阅basic_string)。
- string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits 和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。
- 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个 类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。
以下是string类对象的一些修改操作:
能够灵活使用这些操作是必须的,作为初学者的我们,也应该试着去弄清楚它的底层是怎盐实现的。
那么下面就是我模拟实现出来string类以及她的一些常用操作:
请看代码:
#include<iostream>
#include<string.h>
#include<assert.h>
using namespace std;
class String
{
public:
//迭代器:
typedef char* iterator;
iterator begin()
{
return _str;
}
iterator end()
{
return _str + _size;
}
//构造函数
String(const char* str = "")
{
_size = strlen(str);
_capacity = _size;
_str = new char[_capacity + 1];
strcpy(_str, str);
}
// 构造拷贝
String(const String& s)
:_str(nullptr)
, _size(0)
, _capacity(0)
{
String tmp(s._str);
this->Swap(tmp);
}
//赋值运算符的重载
String& operator=(String s)
{
this->Swap(s);
return *this;
}
//交换两个String对像的内容,供其他功能的使用。
void Swap(String& s)
{
swap(_str, s._str);
swap(_size, s._size);
swap(_capacity, s._capacity);
}
//析构函数
~String()
{
if (_str)
{
delete[] _str;
_size = 0;
_capacity = 0;
}
}
//------------------------------------------------------------------------------
//大于运算符的重载
bool operator<(const String& s)
{
return !(_str > s._str) && !(_str == s._str);
}
//---------------------------------------------------------------------------------
bool operator>(const String& s)
{
int begin = 0;
int end1 = _size;
int end2 = s._size;
while (begin < end1&&begin < end2)
{
if (_str[begin] > s._str[begin])
return true;
else if (_str[begin] == s._str[begin])
{
begin++;
}
else
return false;
}
if (begin == end1 && begin == end2)
{
return false;
}
else if (begin == end1)
return false;
else
return true;
}
//------------------------------------------------------------------------------
bool operator<=(const String& s)
{
return !(_str > s._str);
}
//------------------------------------------------------------------------------
bool operator>=(const String& s)
{
return !(_str < s._str);
}
//------------------------------------------------------------------------------
bool operator==(const String& s)
{
int begin = 0;
int end1 = _size;
int end2 = s._size;
if (end1 != end2)
return false;
else
{
while (begin < end1)
{
if (_str[begin] == s._str[begin])
begin++;
else
return false;
}
if (begin == end1)
return true;
}
}
//------------------------------------------------------------------------------
bool operator!=(const String& s)
{
return !(_str == s._str);
}
//------------------------------------------------------------------------------
//设置容量
void Reserve(size_t n)
{
if (n > _capacity)
{
char* tmp = new char[n + 1];
strcpy(tmp, _str);
delete[](_str);
_str = tmp;
_capacity = n;
}
}
//------------------------------------------------------------------------------
void PushBack(char ch)
{
if (_size == _capacity)
_capacity *= 2;
_str[_size] = ch;
_size++;
_str[_size] = '\0';
}
//------------------------------------------------------------------------------
// "hello" "xxxxxxxxxxxxxxxxxxxxxxxxxx"
void Append(const char* str)
{
if(_size+strlen(str)>_capacity)
Reserve(_capacity +strlen(str));
strcpy(_str + _size, str);
_size += strlen(str);
}
//------------------------------------------------------------------------------
String& operator+=(char ch)
{
if(_size==_capacity)
Reserve(_capacity * 2);
PushBack(ch);
return (*this);
}
//------------------------------------------------------------------------------
String& operator+=(const char* str)
{
Append(str);
return (*this);
}
//------------------------------------------------------------------------------
//在指定位置插入一个字符
void Insert(size_t pos, char ch)
{
String s(*this);
if (_size == _capacity)
_capacity *= 2;
char* arr = s._str + pos;
_str[pos] = ch;
_size++;
strcpy(_str + pos + 1, arr);
}
//------------------------------------------------------------------------------
//在指定位置插入一个字符串
void Insert(size_t pos, const char* str)
{
if (_size == _capacity)
Reserve(_capacity *2);
String s(*this);
int len = strlen(str);
char* arr = s._str + pos;
strcpy(_str + pos, str);
strcpy(_str + pos + len, arr);
_size+=len;
}
//------------------------------------------------------------------------------
//从某个位置开始删除其之后若干个字符
void Erase(size_t pos, size_t len)
{
assert(pos < _size);
if (pos + len >= _size)
{
_size =pos;
_str[pos] = '\0';
}
else
{
char* arr = _str + pos;
char* s = arr + len;
strcpy(_str + pos, s);
_size -= len;
}
}
//------------------------------------------------------------------------------
//查找一个字符,返回其下标。
size_t Find(char ch, size_t pos = 0)
{
size_t begin = pos;
while (begin < _size)
{
if (_str[begin] == ch)
return begin;
else
begin++;
}
return npos;
}
//------------------------------------------------------------------------------
//查找一个字串,返回其首元素的下标
size_t Find(const char* str, size_t pos = 0)
{
size_t begin = pos;
int len = strlen(str);
while (begin < _size)
{
char* arr = _str + begin;
int j = 0;
while (j < len)
{
if (arr[j] == str[j])
{
j++;
}
else
break;
}
if (j == len)
return begin;
begin++;
}
return npos;
}
//------------------------------------------------------------------------------
//返回类中的字符串,供类外调用查看字符串的内容。
char* c_str()
{
return _str;
}
//------------------------------------------------------------------------------
//下标运算符的重载
char& operator[](size_t pos)
{
//assert(pos < _size);
return _str[pos];
}
//------------------------------------------------------------------------------
//返回大小
size_t Size()
{
return _size;
}
//------------------------------------------------------------------------------
//返回容量
size_t Capacity()
{
return _capacity;
}
private:
char* _str;
size_t _size;
size_t _capacity;
static size_t npos;
};
以上就是关于string类的一些常见操作的实现,代码可能不够精简。大家觉得不合理的地方提出来交流一下,大家有更好的实现方式也希望能一起学习分享,哈哈。