#pragma once
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<assert.h>
using namespace std;
namespace dream
{
class string
{
public:
//string() //没必要,直接写一个全缺省
// :_size(0),
// _capacity(0),
// _str(nullptr)
//{}
typedef char* iterator;
//构造函数
string( const char* ps="")
:_size(strlen(ps)),
_capacity(strlen(ps)+16)//初始化,如果空开辟16个空间,如果字符串创建,那就字符串长度+16
{
_str = new char[strlen(ps)+17];
strcpy(_str, ps);
//cout << "test" << endl; //用来测试构造函数是否成功
}
//拷贝构造
string( const string& s)
{//实现深拷贝
_size = s._size;
_capacity = s._capacity;
_str = new char[_capacity + 1];
strcpy(_str, s._str);
}
//赋值重载
string& operator=(const string& s)
{//这不就跟深拷贝一样的么
_size = s._size;
_capacity = s._capacity;
_str = new char[_capacity + 1];
strcpy(_str, s._str);
return *this;
}
//求当前string字符串大小
const size_t size()
{
return _size;
}
//求字符串容量
const size_t capacity()
{
return _capacity;
}
//返回_str的地址
const char* get_c()
{
return _str;
}
//求当前string字符串长度
const size_t length()
{
return size_t();
}
//析构函数
~string()
{
_size = _capacity = 0;
delete[] _str;
cout << "test_析构函数" << endl;
}
//重载【】符号
char& operator[](size_t pos)
{//实现这个基本上就能实现遍历了
return _str[pos];
}
//实现简单的迭代器
iterator begin()
{//头
return _str;
}
iterator end()
{
return _str + _size;
}
//尾插
const string& push_back(char ch)
{
if (_size >= _capacity)
{
reserve(_capacity * 2);
}
_str[_size] = ch;
_size++;
_str[_size] = '\0';
return *this;
}
//扩容函数
void reserve(size_t n)
{//如果扩容函数给的n比_capacity小那就什么都不做,这个条件判断非常重要,不然就会出现bug了
if (n <= _capacity)
return;
else
{//n大于capacity那就扩容
char* tem = new char[n + 1];
strcpy(tem, _str);
delete[] _str; //释放原空间
_str = tem; //找到新地址
_capacity = n; //更改容量
}
}
//扩容函数 resize()
void resize(size_t n,char ch='\0')
{//半缺省,这样就能实现不传参默认填充\0
if (n <= _size)
{//缩容是有代价的
_str[n] = '\0';
n++; //当n过小的时候本质上就是保留前n个
_size = n;
}
else if (_size< n <= _capacity)
{
return;
}
else
{
char* tem = new char[n + 1];
strcpy(tem, _str);
delete[] _str; //释放原空间
_str = tem; //找到新地址
_capacity = n; //更改容量
while (_size < _capacity)
{
_str[_size] = ch;
_size++;
}
//最后一个位置用来放\0
_str[_size] = '\0';
}
}
//头插字符
const string& insert(size_t pos, const char ch)
{//断言
assert(pos <= _size);
if (_size + 1 > _capacity)
{
reserve(2 * _capacity);
}
size_t end = _size+1;
while (end > pos)
{
_str[end] = _str[end - 1];
end--;
}
_str[pos] = ch;
_size++;
return *this;
}
//头插字符串
const string& insert(size_t pos, const char* str)
{//复用头插字符函数
assert(pos <= _size);
int len = strlen(str);
while (len >= 1)
{//把字符串的每一个字符都拿来头插
insert(pos, *(str + len - 1));
len--;
}
return *this;
}
//截取字符串功能
char* substr(size_t pos, size_t n)
{
char* ret = new char[n + 1];
strncpy(ret, _str+pos,n);
ret[n] = '\0';
return ret; //成功实现
}
//删除功能
private:
char* _str;
size_t _size;
size_t _capacity;
};
//流插入重载
ostream& operator<<(ostream& out, dream::string& s)
{
size_t i = 0;
for (auto ch : s)
{
out << ch;
}
return out;
}
流提取重载
//istream& operator>>(istream& in, dream::string& s)
//{
// char ch;
// in >> ch;
// std::cin.get();
// while (ch != ' ' || ch != '\n')
// {
// s.push_back(ch);
// in >> ch;
// if (ch == ' ' || ch == '\n')
// break;
// }//目前这种写法会陷入死循环
// return in;
//}
istream& operator>>(istream& in, dream::string& s)
{
char ch;
ch = in.get();
while (ch != ' ' || ch != '\n')
{
s.push_back(ch);
ch = in.get();//输入一个字符就给string插入一个字符
if (ch == ' ' || ch == '\n')
break;
}//这样就好了,如果你删除==空格的判断条件就等于实现了getline
return in;
}
}
这是我的gitee链接: