🎁个人主页:我们的五年****
🔍系列专栏:C++课程学习****
🎉欢迎大家点赞👍评论📝收藏⭐文章
目录
通过对string的模拟实现,可以对string有更深的理解和认识,大概知道底层的逻辑,以后出现什么问题可以更好的解决。对学习以后的容器也有很大的帮助。
一.string的主体框架:
1.迭代器 2.运算符重载 3.
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<iostream>
#include<cstring>
#include<assert.h>
#include<algorithm>
using namespace std;
namespace bit {
class string {
public:
//迭代器
typedef char* iterator;
typedef const char* const_iterator;
iterator begin();
const_iterator begin()const;
iterator end();
const_iterator end()const;
//构造函数
string(size_t capacity = 4);
string(const string& s);
string(const char* str);
string& operator=(const string& str);
//析构函数
~string();
//异地扩容
void reserve(size_t newcapacity);
//尾插数据
void push_back(char c);
const char* c_str()const;
size_t size()const;
size_t capacity()const;
char& operator[](size_t pos);
const char& operator[](size_t pos)const;
void append(const char* str);
string& operator+=(char ch);
string& operator+=(const char* str);
void insert(size_t pos, char ch);
void insert(size_t pos, const char* str);
void erase(size_t pos = 0, size_t len = npos);
void swap(string& s);
string substr(size_t pos = 0, size_t len = npos);
size_t find(char ch, size_t pos = 0);
size_t find(const char* str, size_t pos = 0);
//运算符重载
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;
//对sring进行清理
void clear();
private:
const static size_t npos = -1;
char* _str;
//有效大小
size_t _size;
//空间的容量
size_t _capacity;
};
//重载流插入和流提取
istream& operator>> (istream& is, string& str);
ostream& operator<< (ostream& os, const string& str);
}
二.string的分析:
🍔构造函数和析构函数:
构造函数常用的是三个,普通构造,拷贝构造,用const char*类型进行构造。
//capacity表示要提前开的空间大小
string::string(size_t capacity)
:_str(new char[capacity + 1])
, _capacity(capacity)
, _size(0)
{
_str[0] = '\0';
}
//拷贝构造
string::string(const string& s)
{
_capacity = s._capacity;
_size = s._size;
_str = new char[_capacity + 1];
strcpy(_str, s._str);
}
string::string(const char* str)
{
size_t length = strlen(str);
_str = new char[length + 1];
_capacity = _size = length;
strcpy(_str, str);
}
string::~string()
{
delete[] _str;
_str = nullptr;
_capacity = _size = 0;
}
🍔迭代器:
//迭代器
typedef char* iterator;
typedef const char* const_iterator;
iterator begin();
const_iterator begin()const;
iterator end();
const_iterator end()const;
🍔赋值运算符重载:
string& string::operator=(const string& str)
{
if (str._capacity > _capacity)
reserve(str._capacity);
strcpy(_str, str._str);
return *this;
}
🍔空间扩容:
void string::reserve(size_t newcapacity)
{
//先判断是否需要扩容
//如果newcapacity小于等于,就不会扩,也不会缩容
if (newcapacity <= _capacity)
return;
char* p = new char[newcapacity + 1];
_capacity = newcapacity;
strcpy(p, _str);
delete[] _str;
_str = p;
}
🍔尾插:
void string::push_back(char c)
{
if (_size == _capacity)
{
//不能直接乘以两倍,_capacity可能为0,乘二还是为0
size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
reserve(newcapacity);
}
_str[_size] = c;
_size++;
}
🍔获取_str,_capacity,_size:
const char* string:: c_str()const
{
return _str;
}
size_t string::size()const
{
return _size;
}
size_t string::capacity()const
{
return _capacity;
}
🍔[]重载,随机访问:
char& string::operator[](size_t pos)
{
assert(pos >= 0 && pos < _size);
return _str[pos];
}
const char& string::operator[](size_t pos)const
{
assert(pos >= 0 && pos < _size);
return _str[pos];
}
🍔在结尾追加字符串
void string::append(const char* s)
{
size_t length = strlen(s);
if(_size + length > _capacity)
reserve(_size + length);
//
strcat(_str, s);
_size += length;
}
🍔在指定位置插入和删除字符串:
void string::insert(size_t pos, char ch)
{
assert(pos >= 0 && pos <= _size);
if (_size == _capacity)
reserve(_capacity * 2);
size_t end = _size + 1;
while (end > pos)
{
_str[end] = _str[end - 1];
end--;
}
_size++;
_str[pos] = ch;
}
void string::insert(size_t pos, const char* str)
{
assert(pos >= 0 && pos <= _size);
size_t length = strlen(str);
if (length + _size > _capacity)
reserve(length + _size);
for (size_t i = _size - 1; i >= pos; i--)
_str[i + length] = _str[i];
_str[_size + length] = 0;
for (size_t i = 0; i < length; i++)
_str[i + pos] = str[i];
}
void string::erase(size_t pos, size_t len)
{
assert(pos >= 0 && pos < _size - 1);
if (len>=_size-pos)
{
_str[pos] = '\0';
_size = pos;
}
else
{
strcpy(_str + pos, _str + pos + len);
_size -= len;
}
}
🍔交换:
void string::swap(string& s)
{
std::swap(s._capacity, _capacity);
std::swap(s._size, _size);
std::swap(s._str, _str);
}
🍔获取子串和寻找元素和字符串:
string string::substr(size_t pos, size_t len)
{
assert(pos >= 0 && pos < _size);
if (len > _size - pos)
{
bit::string substr(_str + pos);
return substr;
}
else
{
bit::string substr(len);
for (size_t i = pos; i < pos+len; i++)
substr += _str[i];
return substr;
}
}
size_t string::find(char ch, size_t pos)
{
for (size_t i = 0; i < pos; i++)
{
if (_str[i] == ch)
return i;
}
return -1;
}
size_t string::find(const char* str, size_t pos)
{
char* p = strstr(_str + pos, str);
return p - _str;
}
🍔运算符重载:
bool string::operator<(const string& s) const
{
return strcmp(_str, s._str)<0;
}
bool string::operator>(const string& s) const
{
return !((*this) <= s);
}
bool string::operator<=(const string& s) const
{
return ((*this) < s || (*this) == s);
}
bool string::operator>=(const string& s) const
{
return ((*this) > s || (*this) == s);
}
bool string::operator==(const string& s) const
{
return strcmp(_str, s._str) == 0;
}
bool string::operator!=(const string& s) const
{
return !((*this) == s);
}
string& string::operator+=(char ch)
{
insert(_size, ch);
return *this;
}
string& string::operator+=(const char* str)
{
insert(_size, str);
return *this;
}
🍔流插入和流提取重载:
istream& operator>>(istream& is, string& s)
{
s.clear();
char it = is.get();
while (it != ' ' && it != '\n')
{
s += it;
it = is.get();
}
return is;
}
ostream& operator<<(ostream& os, const string& s)
{
for (size_t i = 0; i < s.size(); i++)
os << s[i];
return os;
}