前提知识:上一章介绍了库里面关于string的诸多接口,这章我要根据库里的相关接口,自己实现。
1.成员变量:
我们需要定义起始位置,已经有效字符个数和容量。
private:char* _str;size_t _size;size_t _capacity;
2.默认成员函数:
2.1构造函数
默认给的缺省值是空串
string(const char *str = ""): _size(strlen(str)){_capacity = _size;_str = new char[_capacity + 1];strcpy(_str, str);}
2.2拷贝构造函数
//拷贝构造函数string(const string& s){_str = new char (s._capacity + 1);memcpy(_str, s._str, s._size + 1);_size = s._size;_capacity = s._capacity;}
2.3赋值构造
//赋值构造 先调用拷贝构造string& operator = (string tmp){// if (this != &s)// {// string tmp(s);// //this->swap(tmp);// swap(tmp);// }// return *this;swap(tmp);return *this;}
2.4析构函数
//析构函数~string(){delete[] _str;_str = nullptr;_size = 0;_capacity = 0;}
3其他成员函数
3.1交换
//交换void swap(string s){std::swap(_str,s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}
3.2c_str函数
//返回字符串首地址const char* c_str(){return _str;}
3.3元素个数
// 返回元素个数size_t size(){return _size;}
3.4operator[ ]
3.4.1普通版本
//根据下标寻找元素char& operator[](int pos){assert(pos < _size);return _str[pos];}
3.4.2const 版本
//根据下标寻找元素 const版本const char& operator[](int pos) const{assert(pos < _size);return _str[pos];}
3.5迭代器和范围for
3.5.1普通迭代器版本
typedef char* iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}
3.5.2const迭代器版本
const_iterator begin() const{return _str;}const_iterator end() const{return _str + _size;}
3.6扩容
3.6.1reserve
//扩容 不需要返回值,改变容量和长度就行void reserve(size_t n){if (n > _capacity){char * tmp = new char[n + 1];//有结束标识符 \0memcpy(tmp, _str,_size + 1);delete [] _str;_str = tmp;_capacity = n;}}
3.6.2resize
void resize(size_t n ,char ch = '\0'){if (n < _capacity){_size = n;_str[_size] = '\0';}else{reserve(n);for (int i = _size; i < n; ++i){_str[i] = ch;}_size = n;_str[_size] = '\0';}}
3.7尾插
3.7.1尾插字符push_back
void push_back(char ch){//判断是否需要扩容if (_size == _capacity){reserve(_capacity == 0 ? 4 : _capacity * 2);}_str[_size] = ch;_size++;_str[_size] = '\0';//结束标志位}
3.7.2尾插字符串 append
// 尾插 字符串void append(const char* string){size_t len = strlen(string);if (_size + len > _capacity){reserve(_size + len);}strcpy(_str + _size, string);_size += len;//无须给停止标志位,因为是字符串}
3.7.3连接重载 operator +=
// += 实现尾插// this指针指向对象 ,对this解引用就是 对象内容string& operator +=(char ch){push_back(ch);return *this;}string& operator +=(const char *string){append(string);return *this;}
3.8插入insert
3.8.1插入字符
//插入字符void insert(size_t pos,char ch, size_t n){assert(pos <= _size);if (_size + n > _capacity){reserve(_size + n);}//挪动数据size_t end = _size;while (end >= pos && end!= npos){//当一个数字都没有的时候 会发生越界_str[end + n] = _str[end];--end;}//插入数据for (int i = 0; i < n; i++){_str[pos + i] = ch;}_size += n;}
3.8.2插入字符串
//插入字符串void insert(size_t pos, char* str){assert(pos <= _size);size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}//挪动数据size_t end = _size;while (end >= pos && end != npos){_str[end + len] = _str[end];--end;}//插入数据for (size_t i = 0; i < len; i++){_str[pos + i] = str[i];}_size += len;}
3.9擦除erase
//擦除void erase(size_t pos, size_t n = npos){assert(pos <= _size);if (n == npos || pos + n >= _capacity){_str[pos] = '\0';_size = pos;_str[_size] = '\0';}else{size_t end = pos + n;while (end <= _size){_str[pos++] = _str[end++];}_size -= n;}}
3.10查找find
3.10.1查找字符
//发现size_t find(char ch,size_t pos = 0){assert(pos < _size);for (size_t i = pos; i < _size; i++){if (_str[i] == ch){return i;}}return npos;}
3.10.2查找字符串
//发现字符串size_t find(const char* str, size_t pos = 0){assert(pos < _size);const char* ptr = strstr(_str + pos, str);if (ptr){return ptr - _str;}else{return npos;}}
3.11返回子串substr
// 从某个位置开始 返回长度的字符串string substr(size_t pos = 0, size_t len = npos){assert(pos < _size);size_t n = len;if (len == npos || pos + len > _capacity){n = _size - pos;}string tmp;//临时创建一个对象tmp.reserve(n);for (size_t i = 0; i < n; i++){tmp += _str[i];}return tmp;}
3.12清空clear
//清空函数void clear(){_str[_size] = '\0';_size = 0;}
3.13比较
3.13.1 operator <()
//重载实现 string对象的<bool operator <(const string& s) const{int ret = memcmp(_str, s._str, _size < s._size?_size : s._size); // 定义一个变量 用来接收 比较两个字符串 长度较小的那个,如果相等则为0,如果大于则为正值,如果小于则为负。return ret == 0 ? _size < s._size : ret < 0;}
3.13.2operator==()
bool operator == (const string& s) const{return _size == s._size && memcmp(_str, s._str, _size)==0;}
3.13.3 operator<=()
bool operator <= (const string& s) const{return *this < s || *this == s;}
3.13.4operator>()
bool operator > (const string& s) const{return !(*this <= s);}
3.13.5operator>=()
bool operator >= (const string& s) const{return !(*this < s);}
3.13.6operator!=()
bool operator != (const string& s) const{return !(*this == s);}
3.14流插入、提取
3.14.1operator <<
//流插入ostream& operator << (ostream& out, const string& s){for (auto ch : s){out << ch;}return out;}
3.14.2operator >>
//流提取istream& operator >> (istream& in, string& s){s.clear();char ch = in.get();//定义一个字符接收//处理前面缓冲区的空格和换行while (ch == ' ' || ch == '\n'){ch = in.get();}char buff[128];int i = 0;while ( ch != '\n'){buff[i++] = ch;if (i == 127){buff[i] = '\0';s += buff;i = 0;}ch = in.get();}if (i != 0){buff[i] = '\0';s += buff;}return in;}