#include <vector>
#include<iostream> //istream ,ostream
#include<assert.h>
#include<fstream>
using namespace std;
class MyString
{
private:
struct StrNode
{
int ref;//引用计数(表示有多少个客户在使用)
int len;//字符长度
int capc;//容量
char data[0];//柔性数组(要么给0,要么什么也不给)
};
enum{ALGIN=8};//枚举
private:
StrNode* pstr;//结构类型的指针
size_t round_up(size_t n)//对其方式的提升
{
return (n + ALGIN - 1) & ~(ALGIN - 1);
//return ((n - 1) / ALGIN + 1) * ALGIN; 如:1,2,3,4,5,6,7,8=>8 ; 9,10,11,...,16=>16
}
static StrNode* M_Malloc(size_t size)//size为柔性数组所开辟的空间
{
//封装malloc,并对其尾部信息
StrNode* s = (StrNode*)malloc(sizeof(StrNode) + sizeof(char) * size);
if (nullptr == s)
{
exit(1);
}
return s;
}
static StrNode* M_Realloc(StrNode* p, size_t size)
{
StrNode* s = (StrNode*)realloc(p, sizeof(StrNode) + sizeof(char) * size);
if (nullptr == s)
{
exit(1);
}
s->capc = size-1;
return s;
}
static StrNode* cloneStrNode(StrNode* ps)//克隆
{
StrNode* s = M_Malloc(ps->capc + 1);
memmove(s, ps, sizeof(StrNode) + ps->len + 1);
s->ref = 1;
s->len =ps->len;
s->capc = ps->capc;
return s;
}
public:
typedef char value_type;//值类型设置为char
typedef char* iterator; //迭代器设置为char
typedef const char* const_iterator;//常性迭代器,只能指向你,不能修改你
public:
iterator begin()
{
return pstr->data;
}
iterator end()
{
return pstr->data + pstr->len;
}
const iterator begin() const
{
return pstr->data;
}
const iterator end() const
{
return pstr->data + pstr->len;
}
public:
void clear() //清除是将引用计数降下来,当引用计数为0时,才有资格释放
{
if (nullptr != pstr && --pstr->ref == 0)
{
free(pstr);
}
pstr = nullptr;
}
//容量函数
size_t size() const //字符串个数
{
//assert(pstr != nullptr);
return (pstr != nullptr) ? pstr->len : 0;
}
size_t length() const { return size(); }
bool empty() const{ return size() == 0; }
size_t capacity() const
{
return (pstr != nullptr) ? pstr->capc : 0;
}
void reserve(size_t newsz);//保留存储函数
//元素访问函数
char& at(const int index) //写时拷贝
{
return operator[](index);
}
const char& at(const int index) const
{
return operator[](index);
}
char& operator[](const int index)//重载下标运算符
{
assert(pstr != nullptr && index >= 0 && index < pstr->len);
if (pstr->ref > 1)
{
pstr->ref -= 1;
pstr = cloneStrNode(pstr);
}
else
{
return pstr->data[index];
}
}
const char& operator[](const int index) const
{
assert(pstr != nullptr && index >= 0 && index < pstr->len);
return pstr->data[index];
}
char& front()//访问第一个字符
{
return at(0);
}
const char& front() const
{
return at(0);
}
char& back()//访问最后一个字符
{
return at(pstr->len - 1);//return at(size()-1);
}
const char& back()const
{
return at(size() - 1);
}
const char* c_str() const
{
return (pstr == nullptr) ? nullptr : pstr->data;
}
const char* data() const
{
return (pstr == nullptr) ? nullptr : pstr->data;
}
char* data()
{
return (pstr == nullptr) ? nullptr : pstr->data;
}
public:
MyString(const char* p = nullptr) :pstr(nullptr)//构造函数,并对其初始化
{
if (nullptr != p)
{
int n = strlen(p);
int total = round_up(2 * n);//提升为8的倍数
//int total = 2* n;
pstr = M_Malloc(total);//total为柔性数组的大小
pstr->ref = 1;
pstr->len = n;
pstr->capc = total - 1;
strcpy_s(pstr->data, total, p);
}
}
~MyString() //析构函数
{
/*if (nullptr != pstr && --pstr->ref == 0)//表示指向了一个柔性数组这样的结构,且引用计数为0(该字符串已经没人使用)
{
free(pstr);
}
pstr = nullptr;
*/
clear();
}
MyString(const MyString& s) :pstr(s.pstr)//浅拷贝构造函数(当引用计数为0时,才会消亡)
{
if (pstr != nullptr)
{
pstr->ref += 1;
}
}
MyString& operator=(const MyString& sc) //赋值函数
{
if (this == &sc||this->pstr==sc.pstr) return *this;//自己给自己赋值,没有任何意义
clear();//s1=s2,赋值之前,先将s1清除
pstr = sc.pstr;
if (pstr != nullptr)
{
pstr->ref += 1;
}
return *this;
}
MyString(MyString&& sc):pstr(sc.pstr)//移动构造(将堆区空间的资源给另一个空间,引用计数不会发生变化)
{
sc.pstr = nullptr;
}
MyString& operator=(MyString&& sc)//移动赋值
{
if (this == &sc) return *this;
clear();//先将自己的资源释放掉
pstr = sc.pstr;
sc.pstr = nullptr;//移动之后,资源空了,然后将其置空
return *this;
}//s1=std::move(s2);
ostream& operator<<(ostream& out) const //输出流
{
if (pstr != nullptr)
{
out << pstr->data;
}
return out;
}
void Print() const
{
if (pstr != nullptr)
{
cout << pstr->data << endl;
}
}
MyString operator+=(const MyString& sc) ;//字符串对象相加
MyString operator+=(const char* p);//字符串常量相加
MyString& operator += (const char ch)//追加字符
{
char str[2] = { ch,'\0' };
if (pstr == nullptr)
{
*this= MyString(str);
}
else if(pstr->ref==1)
{
if (pstr->capc - pstr->len >= 0)
{
pstr->data[pstr->len] = ch;
pstr->data[++pstr->len] = '\0';
}
else
{
pstr = M_Realloc(pstr, round_up(pstr->len * 2));//扩容
}
}
else
{
pstr->ref -= 1;
pstr = cloneStrNode(pstr);
if (pstr->capc - pstr->len >= 0)
{
pstr->data[pstr->len] = ch;
pstr->data[++pstr->len] = '\0';
}
else
{
pstr = M_Realloc(pstr, round_up(pstr->len * 2));//扩容
}
}
return *this;
}
};
MyString operator+(const char* p, const MyString& sc) ;//字符常量和字符串对象相加
ostream& operator<<(ostream& out, const MyString& s)//全局输出函数
{
s << out;//s.operator<<(out); operator<<(s,out);
return out;
}
int main()
{
MyString s1("yhping");
MyString::iterator it = s1.begin();
for (; it != s1.end(); ++it)
{
//cout << *it << endl;
}
for (char ch:s1)//范围for
{
cout << ch << endl;
}
size_t n = s1.size();
for (int i = 0; i<n; i++)
{
cout << s1.at(i) << " ";
//cout << s1[i] << " ";
}
s1.Print();
const char* str = s1.c_str();
if (str != nullptr)
{
cout << str << endl;
}
return 0;
}
运行结果: