C++之模拟实现string(下)

简介: C++之模拟实现string(下)

五、capacity

1.size

类外成员不能直接访问类的私有属性/数据,因此需要提供一个接口进行访问数据,但是要对数据进行保护,因此用了const传参和传值返回。

访问string中的元素个数。

size_t size()const
    {
      return _size;
    }

2.capacity

访问string的容量。

size_t capacity()const
    {
      return _capacity;
    }

3.empty

判断字符串是否为空。

bool empty()const
    {
      if (_size == 0)
      {
        return true;
      }
      return false;
    }

4.resize

修改字符串的元素个数,可以尾插指定的字符,未指定则默认插入’\0’。

void resize(size_t n, char c = '\0')//更改元素个数
    {
      if (n <= _size)
      {
        _size = n;
        _str[_size] = '\0';
      }
      else
      {
        reserve(n);//先扩容,再加元素
        for (size_t i = _size; i < n; ++i)
        {
          _str[i] = c;
        }
        _str[n] = '\0';
        _size = n;
      }
    }

5.reserve

修改字符串的容量。

void reserve(size_t n)//更改容量大小
    {
      if (n > _capacity)
      {
        char* temp = new char[n + 1];//先开空间再拷贝值(避免因为空间开辟失败的异常使_str原地址也丢失了)
        strcpy(temp, _str);
        delete[] _str;
        _str = temp;
        _capacity = n;
      }
    }

六、access

访问字符串中的字符,运算符[]重载。

1.普通对象的接口(可读可写)

char& operator[](size_t index)//普通对象的接口(可读可写)
    {
      assert(index < _size);
      return _str[index];
    }

2.const对象的接口(只读)

const char& operator[](size_t index)const//const对象的接口(只读)
    {
      assert(index < _size);
      return _str[index];
    }

七、relational operators

1.运算符<重载

bool operator<(const string& s)
    {
      size_t len = _size < s._size ? _size : s._size;
      for (size_t i = 0; i < len; ++i)
      {
        if ((*this)[i] >= s[i])
        {
          return false;
        }
        return true;
      }
    }

2.运算符>重载

bool operator>(const string& s)
    {
      size_t len = _size < s._size ? _size : s._size;
      for (size_t i = 0; i < len; ++i)
      {
        if ((*this)[i] <= s[i])
        {
          return false;
        }
        return true;
      }
    }

3.运算符<=重载

复用>。

bool operator<=(const string& s)
    {
      return !(*this > s);
    }

4.运算符>=重载

复用<。

bool operator>=(const string& s)
    {
      return !(*this < s);
    }

5.运算符==重载

复用<和>。

bool operator==(const string& s)
    {
      return (!((*this) < s)) && (!((*this) > s));
    }

6.运算符!=重载

复用==。

bool operator!=(const string& s)
    {
      return !((*this) == s);
    }

八、String operations

1.find

1.找字符

找一个字符第一次在字符串中出现的下标

// 返回c在string中第一次出现的位置(下标)
    size_t find(char c, size_t pos = 0) const
    {
      assert(pos < _size);
      for (size_t i = 0; i < _size; ++i)
      {
        if ((*this)[i] == c)
        {
          return i;
        }
      }
      return npos;
    }

2.找子串

找一个子串第一次出现在字符串中的下标

复用C语言对字符串的操作——strstr函数(在一个字符串中找子串)

// 返回子串s在string中第一次出现的位置(下标)
    size_t find(const char* s, size_t pos = 0) const
    {
      assert(pos < _size);
      const char* ptr = strstr(_str + pos, s);
      if (ptr == nullptr)
      {
        return npos;
      }
      else
      {
        return ptr - _str;
      }
    }

也可以一个字符一个字符的遍历寻找:

// 返回子串s在string中第一次出现的位置(下标)
    size_t find(const char* s, size_t pos = 0) const
    {
      assert(pos < _size);
      size_t i = 0;
      while (i < _size)
      {
        int flag = 0;
        if ((*this)[i] == s[0])
        {
          size_t k = i;
          for (size_t j = 0; j < strlen(s); ++j, ++k)
          {
            if ((*this)[k] != s[j])
            {
              flag = 1;
            }
          }
          if (flag == 0) return i;
        }
        i++;
      }
      return npos;
    }

2.c_str

返回字符串的地址

const char* c_str()const
    {
      return _str;
    }

九、Non-member function overloads

1.流插入

ostream& operator<<(ostream& _cout, const string& s)
  {
    for (size_t i = 0; i < s.size(); i++)
    {
      _cout << s[i];
    }
    return _cout;
  }

2.流提取

istream& operator>>(istream& _cin, string& s)
  {
    s.clear();//将原来s中的值清除
    char buff[128] = { '\0' };
    size_t i = 0;
    char ch = _cin.get();//这里不能使用getc或者scanf函数的原因是他们都是按照空格' '或者换行'\n'进行分割内容的,所以无法取到空格和换行,因此只能用get()
    while (ch != ' ' || ch != '\n')
    {
      if (i == 127)//缓存部分满了
      {
        s += buff;//将内容存入s,同时将缓存部分情况
        i = 0;
      }
      buff[i++] = ch;
      ch = _cin.get();
    }
    return _cin;
  }

十、私有属性

private:
    char* _str;
    size_t _capacity;
    size_t _size;
    const static size_t npos = -1;//只有这个特例可以这样定义,其他static数据成员都要在类内声明,在类外定义。

总结

以上就是今天要讲的内容,本文介绍了作者自己实现的string类的相关类成员函数,如果文章中的内容有错误或者不严谨的部分,欢迎大家在评论区指出,也欢迎大家在评论区提问、交流。

最后,如果本篇文章对你有所启发的话,希望可以多多支持作者,谢谢大家!

相关文章
|
1月前
|
C++ 容器
|
1月前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
22 1
|
1月前
|
C++ 容器
|
1月前
|
C++ 容器
|
1月前
|
存储 C++ 容器
|
1月前
|
安全 C语言 C++
【C++篇】探寻C++ STL之美:从string类的基础到高级操作的全面解析
【C++篇】探寻C++ STL之美:从string类的基础到高级操作的全面解析
36 4
|
1月前
|
存储 编译器 程序员
【C++篇】手撕 C++ string 类:从零实现到深入剖析的模拟之路
【C++篇】手撕 C++ string 类:从零实现到深入剖析的模拟之路
65 2
|
1月前
|
编译器 C语言 C++
【C++】C++ STL 探索:String的使用与理解(三)
【C++】C++ STL 探索:String的使用与理解
|
1月前
|
存储 编译器 C++
【C++】C++ STL 探索:String的使用与理解(二)
【C++】C++ STL 探索:String的使用与理解
|
1月前
|
编译器 C语言 C++
【C++】C++ STL 探索:String的使用与理解(一)
【C++】C++ STL 探索:String的使用与理解