网站认证值不值得做,工作细胞第二季,友情链接添加在网站中有什么用,给别人做网站挣钱么前言 string的模拟实现其实就是增删改查#xff0c;只不过加入了类的概念。 为了防止与std里面的string冲突#xff0c;所以这里统一用String。
目录
前言
一 初始化和销毁
1.1 构造函数
1.2 析构函数 二 迭代器实现
三 容量大小及操作 四 运算符重载 4.1 bool…前言 string的模拟实现其实就是增删改查只不过加入了类的概念。 为了防止与std里面的string冲突所以这里统一用String。
目录
前言
一 初始化和销毁
1.1 构造函数
1.2 析构函数 二 迭代器实现
三 容量大小及操作 四 运算符重载 4.1 bool operator(const String s) const
4.2 bool operator(const String s) const 4.3 bool operator(const String s) const
4.4 bool operator(const String s) const
4.5 bool operator(const String s) const 4.6 bool operator!(const String s) const 五 字符串操作
5.1 截取操作
5.2 查找操作
六 流插入流提取
6.1 ostream operator(ostream out, const String s)
6.2 istream operator(istream in, String s) 七 string与string相加
String operator(const String s2)
string类模拟实现完整代码
总结 一 初始化和销毁
1.1 构造函数 对于构造函数来说有有参构造和无参构造 所以直接把他们结合起来 default string();copy string (const string str); 1.string();//无参构造
2.string (const string str);//有参构造
String(const char* str ) :_size(strlen(str)), _capacity(_size){_str new char[_capacity1];strcpy(_str, str);} 如果把_str的初始化放在初始化列表会出问题
private:char* _str;size_t _size;size_t _capacity;static const size_t npos -1;
String(const char* str ) :_str(new char [_capacity1]),_size(strlen(str)), _capacity(_size){//_str new char[_capacity1];strcpy(_str, str);}
初始化列表是会按照成员变量的顺序去初始化所以这里 初始化_str_capacity没有初始化所以在开空间的时候会出问题当然你可以换一换位置但是未免太繁琐同时这里不能把_str设置为nullptr如果设置为空那么_size正初始化就会出问题
1.2 析构函数 这里的析构函数没有那么多细节直接释放空间然后处理其他的成员变量就行了
~String(){delete[] _str;//注意这里的delete[],不是delete_str nullptr;_size 0;_capacity 0;} 二 迭代器实现
其实迭代器可以理解为是指针在进行有的底层是指针有的是其他的方法这里我们用指针去模拟实现
//迭代器typedef char* iterator;typedef 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;}
迭代器也需要const类型这样const类型的函数才能去调用所以写两份。注意范围for就是无脑替换迭代器本质和迭代器是一样的。
测试案例
#define _CRT_SECURE_NO_WARNINGS 1
#includeString.h
int main()
{String str(Test string);for (String::iterator it str.begin(); it ! str.end(); it)cout *it;cout \n;for (auto ch : str){cout ch ;}cout endl;return 0;
} 还有反向迭代器这里就不一一列举了想了解的可以参考string类的介绍
三 容量大小及操作
1.capacity()//表示容量大小
2.size()//有效数据大小
3.max_size()//最大有多少数据
4.empty()//是否为空
5.resize()//扩容
6.reserve()//扩容
size_t size()const{return _size;}size_t capacity()const{return _capacity;}size_t max_size()const{return 4294967291;}bool empty()const {return _size 0;}void reserve(size_t n){if (n _capacity){char* tmp new char[n 1];strcpy(tmp, _str);delete[]_str;_str tmp;}_capacity n;}void resize(size_t n, char ch \0){if (n _size){_str[n] \n;_size n;}else{reserve(n);while (_size n){_str[_size] ch;_size;}_str[_size] \0;}}
1.对于empty它是如果为空才是真不为空就假
2.对于resize和reserve来说,从参数列表可以看出resize可以设置初始值也就是可以改变_size,
但是reserve不行同时reserve设置的n如果比capacity小的话是不会造成任何影响或者改变的
3.这里的max_size这里我设置了一个常量但是并没有这么简单因为max_size是根据你当前系统来判断该给多大的因素很多但是实现起来很麻烦这里就简单的设置为初始值了 测试案例
由于其他的测试在之前的string类博客测试过了所以这里就不一一测试了
#define _CRT_SECURE_NO_WARNINGS 1
#includeString.h
int main()
{String str(Test string);cout size: str.size() \n;cout capacity: str.capacity() \n;cout max_size: str.max_size() \n;return 0;
} 四 运算符重载 运算符重载就是,,,,这四种但是其实写一个大于和等于或者写一个小于和等于就行了因为其他的都能复用 4.1 bool operator(const String s) const
bool operator(const String s) const{return strcmp(_str, s._str) 0;} 4.2 bool operator(const String s) const
bool operator(const String s) const{return strcmp(_str, s._str) 0;} 由于上面写了和的运算符重载所以下面这几个直接复用前面的东西就行 注意上面的写法用的是字符串函数进行比较但是库里面用的是模板所以这里有出入如果用模板就不能这样比较了 4.3 bool operator(const String s) const
bool operator(const String s) const{return *this s || *this s;}4.4 bool operator(const String s) const
bool operator(const String s) const{return !(*this s);}
4.5 bool operator(const String s) const
bool operator(const String s) const{return !(*this s);} 4.6 bool operator!(const String s) const
bool operator!(const String s) const{return !(*this s);} 五 字符串操作
5.1 截取操作
String substr(size_t pos 0, size_t len npos)const
String substr(size_t pos 0, size_t len npos)const {assert(pos 0 pos _size);size_t end len pos;//最后的位置String s ;if (len npos || pos len _size)//如果长度已经大于当前字符串长度{len _size - pos;//新长度就等于pos到_size这么长end _size;//}s.reserse(len);//开辟空间for (int i pos; i end; i)//从pos开始到end结束{s _str[i];}return s;} 测试样例 5.2 查找操作
size_t find(char c, size_t pos 0)const
size_t find(char c, size_t pos 0)const{for (int i pos;i _size; i){if (_str[i] c){return i;}}return npos;} 查找一个字符 之间从pos位置开始遍历就行了 size_t find(const char* s, size_t pos 0)const size_t find(const char* s, size_t pos 0)const{char* p strstr(_str pos, s);if (p){return p - _str;}else{return npos;}} 查找一个字符直接用库函数strstr就行 测试用例 六 流插入流提取 由于这里的流插入和流提取不会涉及到私有的成员变量所以不用写成友员函数 6.1 ostream operator(ostream out, const String s)
ostream operator(ostream out, const String s)
{for (auto ch : s){out ch;}return out;
}
6.2 istream operator(istream in, String s)
//流提取
istream operator (istream in, string s)
{s.clear();char ch in.get();while (ch ! ch ! \n){s ch;ch in.get();}return in;
}对于上面这段代码来说我们首先要用一个clear去清理一下因为不清理会导致之前的数据存在。 还有一点就是这段代码并不好因为读字符的时候可能会导致频繁的扩容我们电脑上面的程序可不止一个不能一直中断其他程序来进行这个这样对于计算机的消耗有点大 istream operator(istream in, String s)
{char buff[129];size_t i 0;char ch;ch in.get();while (ch ! ch ! \0){buff[i] ch;if (i 128){buff[i] \0;s buff;i 0;}ch in.get();}if (i 0){buff[i] \0;s buff;}return in;
}这段代码就是对之前的一个改良设置一个数组去存 当存到128个字符的时候再一起把它放进字符串里面去最后还有判断一下如果i!128的情况即可 七 string与string相加
String operator(const String s2) 这里用成员函数来写库里面用的是非成员函数 String operator(const String s2){String ret;ret._size _size s2._size;ret._str new char[_capacity s2._capacity];strcpy(ret._str, _str);strcpy(ret._str _size, s2._str);return ret;}
先开空间然后把两个字符串放进去就行。 string类模拟实现完整代码
#pragma once
#includeiostream
#includeassert.h
using namespace std;
class String
{
public://迭代器typedef char* iterator;typedef 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;}//构造函数String(const char* str ) :_size(strlen(str)), _capacity(_size){_str new char[_capacity1];strcpy(_str, str);}//析构函数~String(){delete[] _str;_str nullptr;_size 0;_capacity 0;}//拷贝构造String(const String s):_str(nullptr),_size(s._size), _capacity(s._capacity){_str new char[_capacity 1];strcpy(_str, s._str);_size s._size;_capacity s._capacity;}//下表访问char operator[](size_t pos){assert(pos _size||pos0);return _str[pos];}void swap(String s){std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}//赋值运算符重载Stringoperator(String tmp){swap(tmp);return *this;}//Capacitysize_t size()const{return _size;}size_t capacity()const{return _capacity;}size_t max_size()const{return 4294967291;}bool empty()const {return _size 0;}void reserse(size_t n){if (n _capacity){char* tmp new char[n 1];strcpy(tmp, _str);delete[]_str;_str tmp;}_capacity n;}void resize(size_t n, char ch \0){if (n _size){_str[n] \n;_size n;}else{reserse(n);while (_size n){_str[_size] ch;_size;}_str[_size] \0;}}//Element accesschar back(){return _str[_size - 1];}const char back()const{return _str[_size - 1];}char front(){return _str[0];}const char front()const {return _str[0];}//Modifiersvoid append(const char* str){size_t n _size strlen(str);if (n _capacity){reserse(n);_capacity n;}strcat(_str, str);_size strlen(str);}void push_back(char ch){if (_size _capacity){reserse(_capacity 0 ? 4 : 2 * _capacity);}_str[_size] ch;_size;_str[_size] \0;}String operator(const String s){append(s._str);return *this;}String operator(const char* str){append(str);return *this;}String operator(char ch){push_back(ch);return *this;}void insert(size_t pos, char ch){assert(pos _size pos 0);if (_size _capacity){reserse(_capacity 0 ? 4 : _capacity * 2);}size_t end _size 1;while (end pos){_str[end] _str[end-1];end--;}_str[pos] ch;_size;}void insert(size_t pos, const char* str){assert(pos _size pos 0);int len strlen(str);if (_size len _capacity){reserse(_size len);}size_t end _size1;while (end pos){_str[end len] _str[end-1];end--;}strncpy(_str pos, str, len);_size len;}void erase(size_t pos 0, size_t len npos){assert(pos 0 pos _size);if (len npos||poslen_size){_str[pos] \0;_size pos;}else{size_t end pos len;while (end _size){_str[end - len] _str[end];end;}_size - len;}}//String operations:const char* c_str()const{return _str;}const char* data()const{return _str;}size_t find(char c, size_t pos 0)const{for (int i pos;i _size; i){if (_str[i] c){return i;}}return npos;}size_t find(const char* s, size_t pos 0)const{char* p strstr(_str pos, s);if (p){return p - _str;}else{return npos;}}String substr(size_t pos 0, size_t len npos)const {assert(pos 0 pos _size);size_t end len pos;String s ;if (len npos || pos len _size){len _size - pos;end _size;}s.reserse(len);for (int i pos; i end; i){s _str[i];}return s;}String operator(const String s2){String ret;ret._size _size s2._size;ret._str new char[_capacity s2._capacity];strcpy(ret._str, _str);strcpy(ret._str _size, s2._str);return ret;}bool operator(const String s) const{return strcmp(_str, s._str) 0;}bool operator(const String s) const{return strcmp(_str, s._str) 0;}bool operator(const String s) const{return *this s || *this s;}bool operator(const String s) const{return !(*this s);}bool operator(const String s) const{return !(*this s);}bool operator!(const String s) const{return !(*this s);}
private:char* _str;size_t _size;size_t _capacity;static const size_t npos -1;
};
//non_member constants
ostream operator(ostream out, const String s)
{for (auto ch : s){out ch;}return out;
}
istream operator(istream in, String s)
{char buff[129];size_t i 0;char ch;ch in.get();while (ch ! ch ! \0){buff[i] ch;if (i 128){buff[i] \0;s buff;i 0;}ch in.get();}if (i 0){buff[i] \0;s buff;}return in;
}总结
以上就是string的全部内容了。