大家好,今天这篇文章介绍的主要是C++STL中String的简单模拟实现
这里我们可以从cplusplus.com - The C++ Resources Network 中找到String,基于给出的函数来构建框架
1.私有变量
size_t _size;
size_t _capacity;
char* _str;
const static size_t npos = -1;
2.四个默认成员函数
//构造
string(const char* str = "");
//析构
~string();
//拷贝构造
string(const string& str);
//赋值重载
string operator = (const string& str);
3.迭代器
//迭代器
typedef char* iterator;
typedef const char* const_iterator;
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
4.访问
char& operator[](size_t pos);
const char& operator[](size_t pos) const;
5.增、删、查
//增
string operator+=(char ch);
void push_back(char& ch);
string& append(const char* str);
string& append(const string& s);
void insert(size_t pos, const char* str);
void insert(size_t pos, string& s);
//删
void erase(size_t pos, size_t len);
//查
size_t find(char ch, size_t pos = 0) const;
size_t find(const char* str, size_t pos = 0) const;
size_t find(const string& s, size_t pos = 0) const;
6.输入输出重载
istream& operator>> (istream& is, string& str);
ostream& operator<< (ostream& out, const string& str);
7。空间相关
void reserve(size_t n = 0);
size_t lenth() const;
size_t capacity() const;
以上就是主要的函数了
运行环境VS2022
我这里采用的声明定义分离的写法,分为2个文件,String.h,String.cpp
String.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include
#include
using namespace std;
//先把框架搭出来
namespace lzp
{
class string
{
public:
typedef char* iterator;
typedef const char* const_iterator;
//检查空间
void cheak_capacity();
void reserve(size_t n = 0);
//迭代器
iterator begin();
iterator end();
const_iterator begin() const ;
const_iterator end() const;
//构造
string(const char* str = "") ;
//析构
~string();
//拷贝构造
string(const string& str);
//赋值重载
string operator = (const string & str);
string operator+=(char ch);
char& operator[](size_t pos);
//其他的函数
const char* c_str() const
{
return _str;
}
/*char* c_str()
{
return _str;
}*/
size_t lenth()
{
return _size;
}
size_t capacity()
{
return _capacity;
}
void clear()
{
_size = 0;
_str[_size] = '\0';//加上这一步,是因为不写的话有特殊情况
}
string& append(const char& ch);
string& append(const char* str);
string& append(const string& s);
void push_back(const char& ch);
void insert(size_t pos, char ch);
void insert(size_t pos, const char* str);
void erase(size_t pos, size_t len);
size_t find(const string& str, size_t pos = 0) const;
size_t find(const char* s, size_t pos = 0) const;
string substr(size_t pos = 0, size_t len = npos);
void swap(string& str);
private:
size_t _size;
size_t _capacity;
char* _str;
const static size_t npos = -1;
};
istream& operator>> (istream& is, string& str);
ostream& operator<< (ostream& out, const string& str);
}
String.cpp
#include "String.h"
namespace lzp
{
//检查空间
void string::cheak_capacity()
{
//如果_size >= _capecity 的话,就要扩容
//其实等于的时候就要扩容了
if (_size >= _capacity)
{
_capacity = _capacity == 0 ? 4 : _capacity * 2;
char* tem = _str;
_str = new char[_capacity + 1];
strcpy(_str, tem);
delete[] tem;
}
}
//提前开好空间
void string::reserve(size_t n)
{
if (n > _capacity)
{
char* tem = new char[n + 1]; //应该要给\0留好空间
strcpy(tem, _str);
delete[] _str;
_str = tem;
_capacity = n;
}
}
//迭代器
string::iterator string::begin()
{
return _str;
}
string::iterator string::end()
{
return _str + _size;
}
string::const_iterator string::begin() const
{
return _str;
}
string::const_iterator string::end() const
{
return _str + _size;
}
//构造
string::string(const char* str)
:_size(strlen(str))
, _capacity(_size)
, _str(nullptr)
{
assert(str);
_str = new char[_capacity + 1];
strcpy(_str, str);
}
//析构
string::~string()
{
_size = 0;
_capacity = 0;
delete[] _str;
}
//拷贝构造
string::string(const string& str)
{
//肯定是深拷贝
//先new一个和str一样大小的空间,再把数据拷贝过去
_str = new char[str._capacity + 1];
_size = str._size;
_capacity = str._capacity;
strcpy(_str, str._str);
}
//赋值重载
string string::operator = (const string& str)
{
//赋值是指两个以及存在的对象进行赋值
char* tem = new char[str._capacity + 1];
delete[] _str;
_str = tem;
_size = str._size;
_capacity = str._capacity;
strcpy(_str, str._str);
return *this;
}
//重载
string string::operator+=(char ch)
{
//先检查空间大小,不够扩容
//然后在后面插入ch
cheak_capacity();
_str[_size] = ch;
_str[_size + 1] = '\0'; //这个置0很关键
_size++;
return *this;
}
char& string::operator[](size_t pos)
{
return _str[pos];
}
//追加
string& string::append(const char& ch)
{
*this += ch;
_size++;
return *this;
}
string& string::append(const char* str)
{
int n = _size + strlen(str);
if (n > _capacity)
{
reserve(n);
}
strcat(_str, str);
//int cnt = n - _size; //strlen(str)
//for (int i = 0; i < cnt; i++)
//{
// _str[_size + i] = str[i];
//}
//_str[_size + cnt] = '\0';
_size = n;
return *this;
}
string& string::append(const string& s)
{
append(s._str);
return *this;
}
void string::push_back(const char& ch)
{
*this += ch;
_size++;
}
void string::insert(size_t pos, char ch)
{
assert(pos >= 0);
cheak_capacity();
//挪动,插入数据
int i = 0;
for (i = _size - 1; i > pos; i--)
{
_str[i + 1] = _str[i];
}
_str[i + 1] = _str[i];
_str[pos] = ch;
_size++;
_str[_size] = '\0';
}
void string::insert(size_t pos, const char* str)
{
assert(pos >= 0);
size_t len = strlen(str);
reserve(len + _size);
//还是挪动,然后插入
int i = 0;
for (int i = _size - 1; i > pos; i--)
{
_str[i + len] = _str[i];
}
_str[i + len] = _str[i];
int j = pos;
for (i = 0; i < len; i++)
{
_str[j++] = str[i];
}
_size += len;
_str[_size] = '\0';
}
void string::erase(size_t pos, size_t len)
{
assert(len <= _size && pos >= 0 && pos < _size);
assert(len <= _size - pos);
//直接往前覆盖
int i = pos;
int count = _size - len;
while (count--)
{
_str[i] = _str[i + len];
i++;
}
_size -= len;
_str[_size] = '\0';
}
size_t string::find(const string& str, size_t pos) const
{
char* ptr = &_str[pos];
if (char* p = strstr(ptr, str._str))
{
return p - &_str[0];
}
return npos;
}
size_t string::find(const char* s, size_t pos) const
{
char* ptr = &_str[pos];
if (char* p = strstr(ptr, s))
{
return p - &_str[0];
}
return npos;
}
string string::substr(size_t pos, size_t len)
{
char* p = &_str[pos];
string s;
size_t cnt = len;
if (cnt != npos)
{
while (cnt--)
{
s += *p;
p++;
}
}
else
{
s.reserve(_size - pos);//这个s没有能用的空间,得提前开好
strcpy(s._str, p);
}
return s;
}
void string::swap(string& str)
{
std::swap(_str, str._str);
std::swap(_size, str._size);
std::swap(_capacity, str._capacity);
}
//标准输入输出
istream& operator>> (istream& in, string& str)
{
str.clear();
char ch = in.get();
while (ch != ' ' && ch != '\n')
{
str += ch;
ch = in.get();
}
return in;
}
ostream& operator<< (ostream& out, const string& str)
{
out << str.c_str();
return out;
}
}
虽然可以简单使用,但是仍存在大量的漏洞,下面我会一一修正