版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_40921797/article/details/82464537
具体关于string函数写时注意,看注释哦
#include<iostream>
#include<string>
using namespace std;
class String
{
public:
String(const char* str = "")
:_str(new char[strlen(str)+1]),
_size(strlen(str)),
_capacity (_size)
{
//利用初始化列表,给出一个缺省的构造函数。
strcpy(_str, str);
}
// s1.Swap(s2);两个对象内容交换
void Swap(String& s)
{
swap(this->_str, s._str);
//swap是库函数
swap(_size, s._size);
swap(_capacity, s._capacity);
}
// String s2(s1) ;拷贝构造函数
String(const String& s)
:_str(NULL),
_size(strlen(s._str)),
_capacity(strlen(s._str))
{
//我利用一个变量调用构造函数,在和我们要拷贝构造的交换,利用出作用域系统会调用析构,释放tmp
String tmp(s._str);
swap(tmp._str, _str);
}
// s1 = s2 ;赋值运算符重载
String& operator=(String s)
{
//我利用同样是不需要自己去开空间,调用构造,转变成构造,然后交换的思想
String tmp(s._str);
swap(tmp._str, _str);
_size = tmp._size;
_capacity = tmp._capacity;
return *this;
}
~String()
{
//析构函数
delete []_str;
_str = NULL;
_size = 0;
_capacity = 0;
}
const char* c_str()
{
return _str;
}
//扩容
void Expand(size_t n)
{
_capacity += n;
char * tmp = new char[_capacity+1];
strcpy(tmp, _str);
swap(tmp, _str);
}
//后面添加数据
void PushBack(char ch)
{
if (_size >= _capacity)
{
Expand(10);
}
_str[_size++] = ch;
_str[_size] = '\0';
}
void PushBack(const char* str)
{
if (_size + strlen(str) >= _capacity)
{
Expand(strlen(str));
}
strcpy((_str + _size), str);
_size += strlen(str);
}
//string 进行的是开空间,但是是不会pop的时候,减空间
void PopBack()
{
_size--;
}
//中间插入,我利用的是memmove库函数,来完成占位的后移
void Insert(size_t pos, char ch)
{
if (_size + 1 >= _capacity)
{
Expand(10);
}
assert(pos >= 0 && pos <= _size);
memmove(_str + pos+1, _str + pos,_size - pos+1);
_str[pos] = ch;
_size++;
}
void Insert(size_t pos, const char* str)
{
if (_size + strlen(str) >= _capacity)
{
Expand(strlen(str));
}
assert(pos >= 0 && pos <= _size);
memmove(_str + pos + strlen(str), _str + pos,_size - pos+1);
strncpy(_str + pos, str, strlen(str));
_size += strlen(str);
}
//pos位置的删除,我同意利用的库函数,实现前移,然后修改size大小
void Erase(size_t pos, size_t n = 1)
{
assert(pos >= 0 && pos < _size);
strcpy(_str + pos, _str + pos + 1);
_size -= 1;
}
//查找
size_t Find(char ch)
{
for (int i = 0; i <(int) _size; i++)
{
if (_str[i] == ch)
return i;
}
return -1;
}
// s1 + 'a' ;+运算符重载+是很浪费空间的,因为在传回时只能传值传回,而+=可以传引用
String operator+(char ch)
{
String tmp(_str);
tmp.PushBack(ch);
return tmp;
}
//+=运算符重载
String& operator+=(char ch)
{
PushBack(ch);
return *this;
}
String operator+(const char* str)
{
String tmp(_str);
tmp.PushBack(str);
return tmp;
}
String& operator+=(const char* str)
{
PushBack(str);
return *this;
}
//比较大小的不需要每个都实现,可以复用,只实现几个,其他的利用就好了。
bool operator>(const String& s)
{
if (strcmp(_str, s._str) > 0)
return true;
else return false;
}
bool operator>=(const String& s)
{
return !(*this < s);
}
bool operator<(const String& s)
{
if (strcmp(_str, s._str) < 0)
return true;
else return false;
}
bool operator<=(const String& s)
{
return !(*this > s);
}
bool operator==(const String& s)
{
if (strcmp(_str, s._str) == 0)
return true;
else return false;
}
bool operator!=(const String& s)
{
return !(*this == s);
}
//输出运算符因为stream需要占用第一个参数,所以不可以写成成员变量,但是又要访问类中私有成员,所以应设为friend友元。
friend ostream& operator<<(ostream& cout, const String&s);
private:
char* _str;
size_t _size;
size_t _capacity;
};
ostream & operator<<(ostream &cout, const String&s)
{
cout << s._str;
return cout;
}