目录
1.string的四大默认函数
1.1构造函数
1.2析构函数
1.3拷贝构造
1.4赋值运算符重载
2.访问string的三种方式
2.1[]访问
2.2迭代器访问
2.3范围for(本质是迭代器)
3.string相关功能的实现
3.1modify
3.2capacity
3.3access
3.4relations
3.5补充
4.补充
1.string的四个默认函数
1.1构造函数
//构造函数String(const char* str = ""):_size(strlen(str)){if (str == nullptr) exit(-1);_capacity = _size == 0 ? 3 : _size;_str = new char[_capacity + 1];strcpy(_str,str);}
1.2析构函数
//析构函数~String() {if (_str == nullptr)assert(false);delete[] _str;_str = nullptr;_size = _capacity = 0;}
1.3拷贝构造
//拷贝构造String(const String& s) {_str = new char[strlen(s._str)+1];strcpy(_str,s._str);}
1.4赋值运算符重载
//赋值运算符String& operator=(const String& s) {if (this != &s) {char* tmp = new char[strlen(s._str)+1];strcpy(tmp,s._str);delete[] _str;_str = tmp;_size = s._size;_capacity = s._capacity;}return *this;}
2.访问string的三种方式
2.1[]访问
char& operator[](size_t pos) {return *(_str + pos);}
2.2迭代器访问
//迭代器typedef char* iterator;typedef const char* const_iterator;iterator begin() {return _str;}iterator begin()const{return _str;}iterator end(){return _str + _size;}iterator end()const{return _str + _size;}
2.3范围for(本质是迭代器)
//范围forcout << "范围for: ";for (auto ch : s1) {cout << ch;}
3.string相关功能的实现
3.1modify
-push_back
//尾插一个字符void push_back(char ch) {//检查是否扩容if (_size + 1 > _capacity)reserve(2*_capacity);//插入数据_str[_size] = ch;++_size;_str[_size] = '\0';}
-+= 字符
//重载String& operator+=(char ch) {push_back(ch);return *this;}
-append
//appendvoid append(const char* str) {int len = strlen(str);if (_size + len > _capacity) //扩容{reserve(_capacity + len);}//插入数据strcat(_str,str);_size += len;}
-+=字符串
//重载+=String& operator+=(const char* str) {append(str);return *this;}
-clear
//clearvoid clear() {_size = 0;_str[_size] = '0';}
-swap
//swapvoid swap(String& s) {std::swap(_str,s._str);std::swap(_size,s._size);std::swap(_capacity, s._capacity);}
-C格式字符串
//C格式的字符串const char* c_str()const{return _str;}
3.2capacity
-size
//获取长度size_t size()const{return _size;}
-capacity
//获取容量size_t size()const{return _capacity;}
-bool empty
bool empty()const{return _size == 0;}
-reserve(扩容)
//reserve(扩容)void reserve(size_t n){if (n < _size) //删除数据{_str[n] = '\0';}if (n > _capacity){//拷贝原来的数据char* tmp = new char[n + 1];strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = n;}}
-resize
void resize(size_t n,char ch = '\0'){if (n < _size) {_size = n;//删除数据_str[_size] = '\0';}else //n>=_size{if (n > _capacity){reserve(n);}//将剩余的字符初始化size_t i = _size;while (i < n){_str[i] = ch;i++;}_size = n;//改变size大小_str[_size] = '\0';}}
3.3access
// accesschar& operator[](size_t pos){return *(_str + pos);}char& operator[](size_t pos)const{return *(_str + pos);}
3.4relations
//relational operatorsbool operator<(const String& s) {return strcmp(_str, s._str) < 0;}bool operator <=(const String& s){return strcmp(_str, s._str) <= 0;}bool operator>(const String& s){return strcmp(_str, s._str) > 0;}bool operator >=(const String& s){return strcmp(_str, s._str) >= 0;}bool operator==(const String& s) {return strcmp(_str,s._str) == 0;}bool operator!=(const String& s){return strcmp(_str, s._str) != 0;}
3.5补充
1.-find //返回c再string中第一次出现的位置
//返回c再string中第一次出现的位置size_t find(char c,size_t pos = 0) {assert(pos < _size);while (pos< _size) {if (_str[pos] == c) {return pos;}pos++;}return npos;}
--find //字符串
//返回子字串在string中第一次出现的位置size_t find(const char* str, size_t pos = 0)const{return strstr(_str,str+pos) - _str - pos;}
2.//在pos位置上插入字符c/字符串str,并返回该字符的位置
-字符
//在pos位置上插入字符c/字符串str,并返回该字符的位置size_t insert(size_t pos ,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--;}//在pos位置插入数据_str[pos] = ch;//更新_size_size++;return pos;}
-字符串
size_t insert(size_t pos, const char* str) {assert(pos < _size);size_t len = strlen(str);//扩容if (_size + len > _capacity) {reserve(_capacity + len);}//挪动数据size_t end = _size + len;while (end - len > pos) {_str[end] = _str[end - len];end--;}//在pos位置插入字符串strncpy(_str + pos ,str,len);//更新_size_size += len;return pos;}
//删除数据
// 删除pos位置上的元素,并返回该元素的下一个位置String& erase(size_t pos,size_t len) {assert(pos < _size);//将pos后的数据删完if (len == npos || pos + len > _size) {_str[pos] = '\0';_size = pos ;}else //删除一部分{//把删除len后面的数据拷贝到pos后strcpy(_str + pos ,_str + pos + len);_size -= len;}return *this;}
3.>>与<<的重载
<<
ostream& operator<<(ostream& _cout, const my_func::String& s){for (auto e : s){_cout << e;}_cout << endl;return _cout;}
>>
istream& operator>>(istream& _cin,my_func::String& s){ s.clear();//清空之前的内容//先往数组里面放,满了/读取到'\n'再往s里面放//这样避免频繁的扩容char buff[128];char ch = cin.get();size_t i = 0;while (ch != '\n'){buff[i++] = ch;if (i == 127) {s += buff;//满了往s里面加i = 0;}ch = cin.get();//继续读取}if (i != 0) {s += buff;}return _cin;}
4.补充
1.reserve与resize
reserve不会改变_size的大小(有效元素的个数)
(当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。)
resize会改变并且用字符初始化多出来的空间
(resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变)
2.str与c_str
c_str是string
类提供的成员函数,用于将string
对象转换为C风格的字符串(以空字符结尾的字符数组)。示例:
c_str在使用cout打印的时候,遇到\0就会停止打印
str 在使用重载后的<<打印,是按_size打印的