#define _CRT_SECURE_NO_WARNINGS 1

#include<iostream>

#include<assert.h>

using namespace std;


class String

{

public:


char* GetStr()

{

return _str;

}


char& operator[] (const size_t pos)

{

char* cur = _str;

cur = cur + pos + 1;

return *cur;

}


void PushBack(const char ch)

{

char* p = new char[_capacity + 1];

strcpy(p, _str);

_str = p;


_str[_size++] = ch;

_str[_size] = '\0';

_capacity = _size + 1;


}


void PopBack()

{

_str[_size - 1] = _str[_size];

char* p = new char[_capacity - 1];

strcpy(p, _str);

_str = p;

}


void  Insert(size_t pos,const char ch)

{

char* p = new char[_capacity + 1];

strcpy(p, _str);

_str = p;


int count = _size - pos + 2;// count 为移动次数

int i = _size;//移动的元素位置

while (count--)//把pos位置及pos后面的  字符 集体向后移一位

{

_str[i + 1] = _str[i];

i--;

}


_str[pos - 1] = ch;

_size++;

_capacity = _size + 1;


}


void  Insert(size_t pos, const char* s)

{


int len = strlen(s);

char* p = new char[_capacity + len];

strcpy(p, _str);

_str = p;


//移动原字符串  空出来空间给待插入的字符串

int moveCount = _size - pos + 2 + (len - 1);// moveCount 为移动次数

int i = _size;//  i  为移动的元素位置

while (moveCount--)//把pos位置及pos后面的  字符 集体向后移一位

{

_str[i + len] = _str[i];

i--;

}


//插入待插入的字符串

int insertCount = len;   //  insertCount  为字符插入次数

int posSource = pos;//  posSource 为原字符串的下标

int posDest = 0;// posDest 为待插入的字符串s的下标

while (insertCount--)

{

_str[posSource - 1] = s[posDest];

posSource++;

posDest++;

}


_size += len;

_capacity = _size + 1;


}

public:

String& operator+= (const String& str)

{


char* p = new char[this->_size + str._capacity];


//拷贝原字符串

strcpy(p, _str);

_str = p;


//拷贝str的字符串

Insert(_size + 1, str._str);

return *this;

}

String& operator+= (const char* str)

{

int len = strlen(str);

char* p = new char[_capacity + len];


//拷贝原字符串

strcpy(p, _str);

_str = p;


//拷贝str字符串

Insert(_size + 1, str);


return *this;

}

String& operator+= (char c)

{

char* p = new char[_capacity + 1];


strcpy(p, _str);

_str = p;


Insert(_size + 1, c);


return *this;

}

void my_Swap(String& str)

{

swap(_str, str._str);

swap(_size, str._size);

_capacity = _size + 1;

str._capacity = str._size + 1;

}

public:


String(char* str = "")

:_str(_New())

{

assert(_str);//检测分配空间是否成功

strcpy(_str, str);

_size = strlen(str);

_capacity = _size + 1;

}


String(String& s)

:_str(_New())

{

assert(_str);

strcpy(_str, s._str);


_size = strlen(s._str);

_capacity = _size + 1;


}


~String()

{

if (_str != NULL)

{

delete[] _str;

}

}


String& operator=(const String& s)

{

_str = _New();

assert(_str);

strcpy(_str, s._str);


_size = strlen(s._str);

_capacity = _size + 1;


return *this;

}


private:


char* _New()

{

char *p = new char[sizeof(String)+1];

return p;

}


private:

char* _str;

int _size;

int _capacity;

};


//test 构造函数 拷贝构造函数  赋值操作符重载  []操作符重载

void test1()

{

String s1("abcd");

cout << s1.GetStr() << endl;

String s2 = s1;

cout << s2.GetStr() << endl;

String s3;

s3 = s2;

cout << s3.GetStr() << endl;

cout << s3[1] << endl;

}


//test  PushBack    PopBack  

//Insert(size_t pos,char ch)

//Insert(size_t pos,char* s)

void test2()

{

String s1("abcd");

cout << s1.GetStr() << endl;

s1.PushBack('e');

cout << s1.GetStr() << endl;

s1.PopBack();

cout << s1.GetStr() << endl;

s1.Insert(2, 'm');

s1.Insert(2, 'n');

cout << s1.GetStr() << endl;

s1.Insert(2, "change");

cout << s1.GetStr() << endl;

}


void test3()

{

String firstname("tan");

String secondname("xiaohui");

firstname += secondname;

cout << firstname.GetStr() << endl;

firstname += " is superman";

cout << firstname.GetStr() << endl;

firstname += '!';

cout << firstname.GetStr() << endl;

firstname.my_Swap(secondname);

cout << firstname.GetStr() << endl;

cout << secondname.GetStr() << endl;

}


int main()

{

//test1();

//test2();

test3();

system("pause");

return 0;

}