蓄电池回收网站建设,成都房地产管理局,wordpress如何设置目录权限,iis5.1新建网站愿所有美好如期而遇 前言
我们模拟实现string类不是为了去实现他#xff0c;而是为了了解他内部成员函数的一些运行原理和时间复杂度#xff0c;在将来我们使用时能够合理地去使用他们。 为了避免我们模拟实现的string类与全局上的string类冲突(string类也在std命名空间中)而是为了了解他内部成员函数的一些运行原理和时间复杂度在将来我们使用时能够合理地去使用他们。 为了避免我们模拟实现的string类与全局上的string类冲突(string类也在std命名空间中)我们用自己的命名空间包起来。
namespace A
{class string{static void test(){}}
}int main()
{A::string::test();
}
接下来我们开始模拟实现string类。 私有的成员变量我们设计无符号整型计算有效字符数量的_size以及记录空间大小的_capacity,最后就是字符指针我们将来开辟好一块空间后存放字符串将由他来指向。 namespace A
{class string{private:size_t _size;size_t _capacity;char* _str;}
} 构造函数 默认是空串并且我们默认比有效字符多开一个字节的空间之后进行拷贝。 string(const char* str )
{_size _capacity strlen(str);_str new char[_capacity 1];strcpy(_str, str);
} 拷贝构造函数: 我们模拟实现string类一定会有空间的开辟一但对象涉及到拷贝就不能是浅拷贝否则会出现一块空间两次释放直接崩掉。 string(const string str)
{_capacity str._capacity;_size str._size;_str new char[_capacity 1];strcpy(_str, str.c_str());
} 赋值运算符重载 同拷贝构造对象也是不能值拷贝否则会出现一块空间释放两次。 string operator(const string str)
{if (this ! str){_capacity str._capacity;_size str._size;char* tmp new char[_capacity 1];strcpy(tmp, str.c_str());delete[] _str;_str tmp;} return *this;
} 析构函数 ~string()
{delete[] _str;_str nullptr;_capacity _size 0;
} 将string转换为const char*我们会在strlen等C的接口处使用比如strlen(s.c_str())因为strlen他的参数是const char*类型的。 const char* c_str() const
{return _str;
} 四个迭代器 只有物理地址空间连续才可以像这样如果是链表我们不能这样做。 typedef char* iterator;
typedef const char* const_iterator;iterator begin()
{return _str;
}iterator end()
{return _str _size;
}const_iterator begin()const
{return _str;
}const_iterator end()const
{return _str _size;
} 尾插单个字符,_capacity和_size都是只考虑有效字符我们在创建空间时默认开空间比_capacity大一。 void push_back(char ch)
{if (_size _capacity){_capacity 0 ? 4 : _capacity * 2;char* tmp new char[_capacity 1];strcpy(tmp, _str);delete[] _str;_str tmp;}_str[_size] ch;_str[_size] \0;
} reserve函数我们使用reserve重新开空间也是只考虑有效字符。 我们实现的reserve不可以缩容。 void reserve(size_t n)
{if (n _capacity){char* tmp _str;//比需求多开一个字节的空间_str new char[n 1];strcpy(_str, tmp);//别忘记_capacity_capacity n;delete[] tmp;}
} 尾插字符串 void append(const char* str)
{size_t len strlen(str);if (_size len _capacity){reserve(_size len);}strcpy(_str _size, str);_size len;
} 赋值运算符的重载 //三个版本的运算符重载
string operator(const string str)
{append(str.c_str());return *this;
}string operator(const char* str)
{append(str);return *this;
}string operator(char ch)
{push_back(ch);return *this;
} 成员函数swap //不用进行深拷贝直接交换地址和大小
void swap(string s)
{std::swap(_size, s._size);std::swap(_capacity, s._capacity);std::swap(_str, s._str);
} 清空字符串函数 void clear()
{memset(_str, 0, _size);
} 返回有效字符数量 判断是否为空 size_t size()const
{return _size;
}bool empty()const
{return _size 0;
} 重载[]运算符我们重载两个版本的重载const版本是因为我们有时候只读不写所以需要这样的重载。 char operator[](size_t index)
{return _str[index];
}const char operator[](size_t index)const
{return _str[index];
} find函数找到后返回下标。strstr找到后返回的是找到的字符串的首地址否则返回空。 size_t find(char c, size_t pos) const
{for (size_t i pos; i _size; i){if (_str[i] c){return i;}}return npos;
}//hello world
size_t find(const char* s, size_t pos 0) const
{char* tmp strstr(_str, s);if (tmp nullptr){return npos;}return tmp - _str;
} insert函数从pos位置插入单个字符以及字符串 string insert(size_t pos, char c)
{assert(pos _size);if (_size _capacity){_capacity 0 ? 4 : _capacity * 2;char* tmp new char[_capacity 1];strcpy(tmp, _str);delete[] _str;_str tmp;}int end _size;while (end (int)pos){_str[end 1] _str[end];end--;}_str[pos] c;_size;return *this;
}//pos是下标
string insert(size_t pos, const char* str)
{assert(pos _size);int len strlen(str);if (len pos _capacity){reserve(len pos);}int end _size;while (end (int)pos){_str[end len] _str[end];end--;}strncpy(_str pos, str, len);_size len;return *this;
} erase函数删除从pos节点开始的len个字符 string erase(size_t pos, size_t len)
{//如果pos size就和没删除一样相当于删\0assert(pos _size);//从pos位置删除len个字符,也就是pos后的字符全部删掉//传的len值接近npos,poslen可能溢出也会有未知错误if (len npos || pos len _size){_str[pos] \0;_size pos;}else{strcpy(_str pos, _str pos len);_size - len;}return *this;
} substr截取从pos位置开始长度为len的字符串 在他返回时就是对象的值拷贝会有临时对象产生临时对象就需要我们自己写的拷贝构造函数了。 string substr(size_t pos 0, size_t len npos)
{assert(pos _size);int end;string str;//hello world 2 3if (len npos || pos len _size){end _size;}else{end pos len;}//记得给str扩容str.reserve(end - pos);while (end pos){str _str[pos];}return str;
}