模拟实现string【C++】

06-29 1061阅读

文章目录

  • 全部的实现代码放在了文章末尾
  • 准备工作
    • 包含头文件
    • 定义命名空间和类
      • 类的成员变量
      • 构造函数
        • 默认构造
        • 拷贝构造
        • 重载赋值拷贝函数
        • 析构函数
        • 迭代器和获取迭代器
          • 迭代器
          • 获取迭代器
          • resize【调整size】
            • 图解
            • reserve【调整capacity】
            • empty【判断串是否为空】
            • operator[]
            • append
            • push_back
            • operator+=
            • insert【在pos之前插入字符串】
            • erase【删除从pos开始的len个字符】
            • swap
            • find
            • substr
            • operator+
            • compare
            • 比较运算符重载
              • operator>
              • operator==
              • operator
              • operator if (n _capacity) 当要调整的容量n大于最大容量时,就要扩容 { char* tmp = new char[n +1];申请size+1个空间,那多出来的1是给'\0'的 strcpy(tmp, _str);拷贝字符串(把右参数拷贝给左参数) delete[] _str;释放扩容前str指向的空间 _str = tmp;完成扩容 for (; _size _str[_size] = c; } _str[_size] = '\0'; 补完之后加上字符串结束标志'\0' _capacity = n;更新最大容量 } else { if (n _size)如果调整之后的size 大于 原来的size 就要把少(n-size)的有效字符用c补上 { for (; _size

                图解

                模拟实现string【C++】

                模拟实现string【C++】


                reserve【调整capacity】

                模拟实现string【C++】


                empty【判断串是否为空】

                模拟实现string【C++】


                operator[]

                返回值要是char&这样才能像字符数组一样访问和修改串中的字符

                模拟实现string【C++】


                append

                模拟实现string【C++】

                模拟实现string【C++】


                push_back

                可以直接服用append

                模拟实现string【C++】


                operator+=

                也可以直接服用append

                模拟实现string【C++】


                insert【在pos之前插入字符串】

                模拟实现string【C++】


                erase【删除从pos开始的len个字符】

                模拟实现string【C++】


                swap

                因为存放字符串的空间是在堆区开辟的,用成员str去指向的

                所以直接交换两个对象的str中存放的地址就可以完成存储的字符串的交换了

                不需要拷贝

                模拟实现string【C++】

                模拟实现string【C++】


                find

                模拟实现string【C++】


                substr

                模拟实现string【C++】


                operator+

                直接复用operator+=

                因为+不改变字符串本身,所以要用一个临时对象存储+=之后的字符,再用传值返回即可

                模拟实现string【C++】


                compare

                模拟实现string【C++】


                比较运算符重载

                operator>

                复用compare

                模拟实现string【C++】


                operator==

                复用compare

                模拟实现string【C++】


                operator

                pmark复用operator>和operator==

                模拟实现string【C++】


                operator>

                复用operator>和operator==

                模拟实现string【C++】


                operator

                模拟实现string【C++】


                operator!=

                复用operator==

                模拟实现string【C++】


                c_str

                作用是获取string对象中的str成员。

                一般是要在C++中使用C语言函数时使用,因为C语言不支持string,所以只能用字符指针代替一下

                模拟实现string【C++】

                operator char str[100]; 存储 输入的 每一行的字符 int sum = 0; 使用sum记录输入的 每一行 的字符个数 char c = 0; \n是换行符(回车),所以 没遇到 \n就 没换行 while ((c = is.get()) != '\n') 一次读取一个字符 { if (sum == 99) 当sum等于99时说明 str数组存不下了 { str[sum] = '\0'; 末尾加上了\0才是字符串 obj += str; 使用+=把str数组中的字符先加上去 sum = 0; sum置成0,继续记录 } else 否则 { 把读取到的字符存进str数组里 str[sum++] = c; } } sum!=0说明最后输入的最后一行字符个数 小于99个,没有+=上 if (sum != 0) { str[sum] = '\0'; 末尾加上了\0才是字符串 obj += str; 使用+=把str数组中的字符先加上去 } return is; 为支持链式编程,返回 输入流对象 的引用 } class string { public: typedef char* iterator; typedef const char* const_iterator; string(const string& obj); string(const char* str = ""); string& operator=(const string&obj); ~string(); iterator begin(); const_iterator begin() const; iterator end(); const_iterator end() const; size_t size() const; size_t capacity() const; void resize(size_t n, char c='\0'); void reserve(size_t n = 0); void clear(); bool empty() const; char& operator[](size_t pos); const char& operator[](size_t pos)const; string& append(const string& obj); string& append(char ch); void push_back(char c); string& operator+=(const string& obj); string& operator+=(char c); string& assign(const string& str); string& insert(size_t pos, const string& str); string& insert(size_t pos,char c); string& erase(size_t pos = 0, size_t len = npos); void swap(string& str); const char* c_str() const; size_t find(const string& str, size_t pos = 0) const; size_t find(char c, size_t pos = 0) const; string substr(size_t pos = 0, size_t len = npos) const; int compare(const string& str) const; string operator+(const string& obj)const; string operator+(char c)const; bool operator(const string&obj)const; bool operator const size_t string::npos = -1; string::string(const string& obj)//因为成员在堆区申请了空间所以要写深拷贝的拷贝构造 { _str = new char[obj._size + 1];// 申请size + 1个空间,那多出来的1是给'\0'的 strcpy(_str, obj._str);//使用该函数把字符串把obj中的字符串拷贝过来 _capacity = obj._capacity; _size = obj._size; } string::string(const char* str) //让str的缺省值为""(空字符串) :_size(strlen(str))//构造函数会先走成员初始化列表,借此先计算出size { assert(str != nullptr);//防止传入的字符指针是空的 _str = new char[_size + 1];//申请size+1个空间,那多出来的1是给'\0'的 strcpy(_str, str);//使用该函数把字符串str中的字符拷贝过来 _capacity = _size;//设置初始最大容量和size一样大 } string& string::operator=(const string&obj) { if (this != &obj)//防止自己赋值给自己 { delete[] _str;//先释放接收赋值之前str指向的堆区空间 //因为接收赋值之后,str中存放的地址就被覆盖了 _str = new char[obj._size + 1];//申请size+1个空间,那多出来的1是给'\0'的 strcpy(_str, obj._str);//拷贝字符串(把右参数拷贝给左参数) _size = obj._size; _capacity = obj._capacity; } return *this; } string::~string() { delete[] _str;//释放str指向的堆区空间 _str = nullptr; _size = 0; _capacity = 0; } string::iterator string::begin()//普通起始迭代器 { return _str; } string::const_iterator string::begin() const//const起始迭代器 { return _str; } string::iterator string::end()//普通结束迭代器 { return _str + _size; } string::const_iterator string::end() const//const结束迭代器 { return _str + _size; } size_t string::size() const { return _size; } void string::resize(size_t n,char c) { if (n _capacity)//当要调整的size,n大于最大容量时,就要扩容 { char* tmp = new char[n +1];//申请size+1个空间,那多出来的1是给'\0'的 strcpy(tmp, _str);//拷贝字符串(把右参数拷贝给左参数) delete[] _str;//释放扩容前str指向的空间 _str = tmp;//完成扩容 for (; _size _str[_size] = c; } _str[_size] = '\0'; //补完之后加上字符串结束标志'\0' _capacity = n;//更新最大容量 } else { if (n _size)//如果调整之后的size 大于 原来的size //就要把少(n-size)的有效字符用c补上 { for (; _size _capacity)//当要调整的容量n大于capacity时,才扩容 { char* tmp = new char[n + 1];//申请size+1个空间,那多出来的1是给'\0'的 strcpy(tmp, _str);//拷贝字符串(把右参数拷贝给左参数) delete[] _str;//拷贝之后再释放旧空间 _str = tmp;//指向新开辟的空间 _capacity = n;//更改最大容量 } } void string::clear() { _size = 0; _str[0] = '\0'; } bool string::empty() const { return _size == 0;//如果size==0就为真,就会return true //如果size!=0就为假,就会return false } char& string::operator[](size_t pos) { assert(pos assert(pos 右 // 返回值等于0就是 左=右 // 返回值小于0就是 左 //使用string.h里面的 strcmp即可完成判断 return strcmp(_str, obj._str); } string string::operator+(const string& obj)const { string tmp(*this);//拷贝构造出一个临时对象 tmp += obj;//让临时对象去+=,就不会改变字符串自己了 return tmp;//传值返回 } string string::operator+(char c)const { string tmp(*this);//拷贝构造出一个临时对象 tmp += c; return tmp; } bool string::operator(const string& obj)const { if (compare(obj) > 0)//返回值大于0就是 左>右 //即调用函数的对象>传入的对象 return true; else return false; } bool string::operator if (!(*this = obj))// =取反 { return true; } else return false; } bool string::operator>=(const string& obj)const { //大于等于 是 大于或者等于 if (*this > obj || *this == obj) return true; else return false; } bool string::operator //小于等于就是 不大于,即大于取反 if (!(*this obj)) return true; else return false; } bool string::operator==(const string& obj)const { if (compare(obj) == 0)//返回值大于0就是 左=右 //即调用函数的对象=传入的对象 return true; else return false; } bool string::operator!=(const string& obj)const { //不等于就是 等于取反 if (!(*this==obj)) return true; else return false; } //ostream是输出流对象,比如我们常用的cout就是 ostream实例化的对象 ostream& operator const char* p = obj.c_str();//获取string对象中的 str成员 os (istream& is, string& obj) { char str[100];//存储 输入的 每一行的字符 int sum = 0;//使用sum记录输入的 每一行 的字符个数 char c = 0; //\n是换行符(回车),所以 没遇到 \n就 没换行 while ((c = is.get()) != '\n')//一次读取一个字符 { if (sum == 99)//当sum等于99时说明 str数组存不下了 { str[sum] = '\0';//末尾加上了\0才是字符串 obj += str;//使用+=把str数组中的字符先加上去 sum = 0;//把sum置成0,继续记录 } else//否则 { //把读取到的字符存进str数组里 str[sum++] = c; } } //sum!=0说明最后输入的最后一行字符个数 小于99个,没有+=上 if (sum != 0) { str[sum] = '\0';//末尾加上了\0才是字符串 obj += str;//使用+=把str数组中的字符先加上去 } return is;//为支持链式编程,返回 输入流对象 的引用 } }

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]