• C++(string 类模拟实现)


    前提知识:上一章介绍了库里面关于string的诸多接口,这章我要根据库里的相关接口,自己实现。


    1.成员变量:

    我们需要定义起始位置,已经有效字符个数和容量。

    1. private:
    2. char* _str;
    3. size_t _size;
    4. size_t _capacity;

    2.默认成员函数:

    2.1构造函数

    默认给的缺省值是空串

    1. string(const char *str = "")
    2. : _size(strlen(str))
    3. {
    4. _capacity = _size;
    5. _str = new char[_capacity + 1];
    6. strcpy(_str, str);
    7. }

    2.2拷贝构造函数 

    1. //拷贝构造函数
    2. string(const string& s)
    3. {
    4. _str = new char (s._capacity + 1);
    5. memcpy(_str, s._str, s._size + 1);
    6. _size = s._size;
    7. _capacity = s._capacity;
    8. }

    2.3赋值构造

    1. //赋值构造 先调用拷贝构造
    2. string& operator = (string tmp)
    3. {
    4. // if (this != &s)
    5. // {
    6. // string tmp(s);
    7. // //this->swap(tmp);
    8. // swap(tmp);
    9. // }
    10. // return *this;
    11. swap(tmp);
    12. return *this;
    13. }

    2.4析构函数

    1. //析构函数
    2. ~string()
    3. {
    4. delete[] _str;
    5. _str = nullptr;
    6. _size = 0;
    7. _capacity = 0;
    8. }

    3其他成员函数

    3.1交换

    1. //交换
    2. void swap(string s)
    3. {
    4. std::swap(_str,s._str);
    5. std::swap(_size, s._size);
    6. std::swap(_capacity, s._capacity);
    7. }

    3.2c_str函数

    1. //返回字符串首地址
    2. const char* c_str()
    3. {
    4. return _str;
    5. }

    3.3元素个数

    1. // 返回元素个数
    2. size_t size()
    3. {
    4. return _size;
    5. }

    3.4operator[ ]

    3.4.1普通版本

    1. //根据下标寻找元素
    2. char& operator[](int pos)
    3. {
    4. assert(pos < _size);
    5. return _str[pos];
    6. }

    3.4.2const 版本

    1. //根据下标寻找元素 const版本
    2. const char& operator[](int pos) const
    3. {
    4. assert(pos < _size);
    5. return _str[pos];
    6. }

     

    3.5迭代器和范围for

    3.5.1普通迭代器版本

    1. typedef char* iterator;
    2. iterator begin()
    3. {
    4. return _str;
    5. }
    6. iterator end()
    7. {
    8. return _str + _size;
    9. }

    3.5.2const迭代器版本

    1. const_iterator begin() const
    2. {
    3. return _str;
    4. }
    5. const_iterator end() const
    6. {
    7. return _str + _size;
    8. }

    3.6扩容

    3.6.1reserve

    1. //扩容 不需要返回值,改变容量和长度就行
    2. void reserve(size_t n)
    3. {
    4. if (n > _capacity)
    5. {
    6. char * tmp = new char[n + 1];//有结束标识符 \0
    7. memcpy(tmp, _str,_size + 1);
    8. delete [] _str;
    9. _str = tmp;
    10. _capacity = n;
    11. }
    12. }

    3.6.2resize

    1. void resize(size_t n ,char ch = '\0')
    2. {
    3. if (n < _capacity)
    4. {
    5. _size = n;
    6. _str[_size] = '\0';
    7. }
    8. else
    9. {
    10. reserve(n);
    11. for (int i = _size; i < n; ++i)
    12. {
    13. _str[i] = ch;
    14. }
    15. _size = n;
    16. _str[_size] = '\0';
    17. }
    18. }

    3.7尾插

    3.7.1尾插字符push_back

    1. void push_back(char ch)
    2. {
    3. //判断是否需要扩容
    4. if (_size == _capacity)
    5. {
    6. reserve(_capacity == 0 ? 4 : _capacity * 2);
    7. }
    8. _str[_size] = ch;
    9. _size++;
    10. _str[_size] = '\0';//结束标志位
    11. }

    3.7.2尾插字符串 append

    1. // 尾插 字符串
    2. void append(const char* string)
    3. {
    4. size_t len = strlen(string);
    5. if (_size + len > _capacity)
    6. {
    7. reserve(_size + len);
    8. }
    9. strcpy(_str + _size, string);
    10. _size += len;
    11. //无须给停止标志位,因为是字符串
    12. }

    3.7.3连接重载 operator +=

    1. // += 实现尾插
    2. // this指针指向对象 ,对this解引用就是 对象内容
    3. string& operator +=(char ch)
    4. {
    5. push_back(ch);
    6. return *this;
    7. }
    8. string& operator +=(const char *string)
    9. {
    10. append(string);
    11. return *this;
    12. }

    3.8插入insert

    3.8.1插入字符

    1. //插入字符
    2. void insert(size_t pos,char ch, size_t n)
    3. {
    4. assert(pos <= _size);
    5. if (_size + n > _capacity)
    6. {
    7. reserve(_size + n);
    8. }
    9. //挪动数据
    10. size_t end = _size;
    11. while (end >= pos && end!= npos)
    12. {
    13. //当一个数字都没有的时候 会发生越界
    14. _str[end + n] = _str[end];
    15. --end;
    16. }
    17. //插入数据
    18. for (int i = 0; i < n; i++)
    19. {
    20. _str[pos + i] = ch;
    21. }
    22. _size += n;
    23. }

    3.8.2插入字符串

    1. //插入字符串
    2. void insert(size_t pos, char* str)
    3. {
    4. assert(pos <= _size);
    5. size_t len = strlen(str);
    6. if (_size + len > _capacity)
    7. {
    8. reserve(_size + len);
    9. }
    10. //挪动数据
    11. size_t end = _size;
    12. while (end >= pos && end != npos)
    13. {
    14. _str[end + len] = _str[end];
    15. --end;
    16. }
    17. //插入数据
    18. for (size_t i = 0; i < len; i++)
    19. {
    20. _str[pos + i] = str[i];
    21. }
    22. _size += len;
    23. }

     

    3.9擦除erase

    1. //擦除
    2. void erase(size_t pos, size_t n = npos)
    3. {
    4. assert(pos <= _size);
    5. if (n == npos || pos + n >= _capacity)
    6. {
    7. _str[pos] = '\0';
    8. _size = pos;
    9. _str[_size] = '\0';
    10. }
    11. else
    12. {
    13. size_t end = pos + n;
    14. while (end <= _size)
    15. {
    16. _str[pos++] = _str[end++];
    17. }
    18. _size -= n;
    19. }
    20. }

    3.10查找find

    3.10.1查找字符

    1. //发现
    2. size_t find(char ch,size_t pos = 0)
    3. {
    4. assert(pos < _size);
    5. for (size_t i = pos; i < _size; i++)
    6. {
    7. if (_str[i] == ch)
    8. {
    9. return i;
    10. }
    11. }
    12. return npos;
    13. }

    3.10.2查找字符串

    1. //发现字符串
    2. size_t find(const char* str, size_t pos = 0)
    3. {
    4. assert(pos < _size);
    5. const char* ptr = strstr(_str + pos, str);
    6. if (ptr)
    7. {
    8. return ptr - _str;
    9. }
    10. else
    11. {
    12. return npos;
    13. }
    14. }

    3.11返回子串substr

    1. // 从某个位置开始 返回长度的字符串
    2. string substr(size_t pos = 0, size_t len = npos)
    3. {
    4. assert(pos < _size);
    5. size_t n = len;
    6. if (len == npos || pos + len > _capacity)
    7. {
    8. n = _size - pos;
    9. }
    10. string tmp;//临时创建一个对象
    11. tmp.reserve(n);
    12. for (size_t i = 0; i < n; i++)
    13. {
    14. tmp += _str[i];
    15. }
    16. return tmp;
    17. }

    3.12清空clear

    1. //清空函数
    2. void clear()
    3. {
    4. _str[_size] = '\0';
    5. _size = 0;
    6. }

    3.13比较

    3.13.1 operator <()

    1. //重载实现 string对象的<
    2. bool operator <(const string& s) const
    3. {
    4. int ret = memcmp(_str, s._str, _size < s._size?_size : s._size); // 定义一个变量 用来接收 比较两个字符串 长度较小的那个,如果相等则为0,如果大于则为正值,如果小于则为负。
    5. return ret == 0 ? _size < s._size : ret < 0;
    6. }

    3.13.2operator==()

    1. bool operator == (const string& s) const
    2. {
    3. return _size == s._size && memcmp(_str, s._str, _size)==0;
    4. }

    3.13.3 operator<=()

    1. bool operator <= (const string& s) const
    2. {
    3. return *this < s || *this == s;
    4. }

    3.13.4operator>()

    1. bool operator > (const string& s) const
    2. {
    3. return !(*this <= s);
    4. }

    3.13.5operator>=()

    1. bool operator >= (const string& s) const
    2. {
    3. return !(*this < s);
    4. }

    3.13.6operator!=()

    1. bool operator != (const string& s) const
    2. {
    3. return !(*this == s);
    4. }

    3.14流插入、提取

    3.14.1operator <<

    1. //流插入
    2. ostream& operator << (ostream& out, const string& s)
    3. {
    4. for (auto ch : s)
    5. {
    6. out << ch;
    7. }
    8. return out;
    9. }

    3.14.2operator >>

    1. //流提取
    2. istream& operator >> (istream& in, string& s)
    3. {
    4. s.clear();
    5. char ch = in.get();//定义一个字符接收
    6. //处理前面缓冲区的空格和换行
    7. while (ch == ' ' || ch == '\n')
    8. {
    9. ch = in.get();
    10. }
    11. char buff[128];
    12. int i = 0;
    13. while ( ch != '\n')
    14. {
    15. buff[i++] = ch;
    16. if (i == 127)
    17. {
    18. buff[i] = '\0';
    19. s += buff;
    20. i = 0;
    21. }
    22. ch = in.get();
    23. }
    24. if (i != 0)
    25. {
    26. buff[i] = '\0';
    27. s += buff;
    28. }
    29. return in;
    30. }

  • 相关阅读:
    SqlSugar 5.联表查询
    react租房项目实战 1 项目介绍、项目搭建
    苏宁API接口解析,实现按关键字搜索suning商品
    网络渗透测试:Wireshark抓取qq图片
    Vue底层监测数据变化的原理
    极智开发 | 腾讯云ECS本地开发环境搭建
    yolov8模型训练、目标跟踪
    设备树覆盖:概念与术语
    memmove函数详解 看这一篇就够了-C语言(函数讲解、函数实现、使用用法举例、作用、自己实现函数 )
    ArGIS Engine专题(13)之矢量要素图层符号化(单一符号化渲染)
  • 原文地址:https://blog.csdn.net/weixin_45476980/article/details/133441434