【C++】—— string模拟实现(一)

简介: 【C++】—— string模拟实现

前言:

       学习了string的使用,总感觉了解不是很深厚;自己模拟实现string类来帮助自己理解。

       这里只是实现了一部分内容(并没有实现完整的string类)。

先来实现string类里面的成员变量:

#include<iostream>
namespace HL
{
  class string
  {
    public:
  private:
    char* _str;
    size_t _size;
    size_t _capacity;
    const static size_t npos;
  };
 
  const size_t HL::string::npos = -1;
}

一、string默认成员函数(构造、析构、赋值运算符重载)

       1.1、构造函数

1> 默认构造

       默认构造函数就是不需要传参的构造函数;这里实现就开辟一个字符的空间存放 '\0'即可(_capacity不包括 '\0' )。

string()
    {
      _str = new char[1];
      _str[0] = '\0';
      _size = 0;
      _capacity = 0;
    }

2> 拷贝构造

       拷贝构造,在实现时需要注意:是深拷贝,而不是浅拷贝(值拷贝)。

深拷贝(深拷贝简单来说就是,要开辟一块新的空间,把原空间里的值拷贝到新的空间里)。

    string(const string& str)
    {
      _str = new char[str._capacity + 1];
      memcpy(_str, str._str, str._size + 1);
      _size = str._size;
      _capacity = str._capacity;
    }

3> 其他构造

       其他构造函数就有很多了,这里就实现以下这几个:

      string (const char* s);

    string(const char* s)
    {
      size_t len = strlen(s);
      _str = new char[len + 1];
      memcpy(_str, s, len + 1);
      _size = len;
      _capacity = len;
    }

      string (const char* s, size_t n);

    string(const char* s, size_t n)
    {
      size_t len = strlen(s);
      if (n > len)
      {
        n = len;
      }
      _str = new char[n + 1];
      memcpy(_str, s, n);
      _str[n] = '\0';
      _size = n;
      _capacity = n;
    }

       string (size_t n, char c);

    string(size_t n, char c)
    {
      _str = new char[n + 1];
      for (size_t i = 0; i < n; i++)
      {
        _str[i] = c;
      }
      _str[n] = '\0';
      _size = n;
      _capacity = n;
    }

       1.2、析构函数

       析构函数比较简单,释放开辟的资源即可;

    ~string()
    {
      delete[] _str;
      _str = nullptr;
      _size = _capacity = 0;
 
    }

       1.3、赋值运算符重载    

       赋值运算符有3个重载,这里就一一实现:

       string& operator= (const string& str );

实现这个有很多种方法,

       可以释放原空间,再开辟新的空间,将数据拷贝到新的空间中去

    string& operator=(const string& str)
    {
      delete[] _str;
      _str = new char[str._capacity];
      memcpy(_str, str._str, str._size + 1);
      _size = str._size;
      _capacity = str._capacity;
      return *this;
    }

可以调用拷贝构造,构造一个tmp、再将tmp与*this 中的值进行交换(要实现交换函数)

template <typename T>
void Swap(T& x, T& y)
{
  T tmp = x;
  x = y;
  y = tmp;
}
string& operator= (const string& str)
{
    string tmp(str);
    Swap(_str, tmp._str);
    Swap(_size, tmp._size);
    Swap(_capacity, tmp._capacity);
    return *this;
}

这里如果已经实现string类swap成员函数,就可以直接调用。

      string& operator= (const char* s );      

    /*string& operator= (const char* s)
    {
      size_t len = strlen(s);
      delete[] _str;
      _str = new char[len + 1];
      memcpy(_str, s, len + 1);
      _size = _capacity = len;
      return *this;
    }*/
    string& operator= (const char* s)
    {
      string tmp(s);
      Swap(_str, tmp._str);
      Swap(_size, tmp._size);
      Swap(_capacity, tmp._capacity);
      return *this;
    }

       string& operator= (char c );

    string& operator= (char c)
    {
      delete[] _str;
      _str = new char[2];
      _str[0] = c;
      _str[1] = '\0';
      _size = _capacity = 1;
      return *this;
    }

二、元素访问与迭代器

       2.1、迭代器

       迭代器,虽然在string类中使用的不是很多,但在后面的容器中有大用处。

       (在string类中就可以简单的理解成指针)。

    //迭代器
    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);
    }

       实现了迭代器之后,范围for这个语法糖就可以使用了(底层就是迭代器)。        

       2.2、下标访问元素

       实现下标访问,就是 [ ]运算符重载。

    //下标访问 [ ]
    char& operator[] (size_t pos)
    {
      assert(pos >= _size);
      return *(_str + pos);
    }
    const char& operator[] (size_t pos) const
    {
      assert(pos >= _size);
      return *(_str + _size);
    }

       at函数和 [ ] 运算符重载原理一样,这里就不重复写了。

三、增删查改

       在实现增之前,要先实现一个函数,就是调整空间大小的(扩容来用)。

    //扩容
    void reserve(size_t n)
    {
      if (n > _capacity)
      {
        char* s = new char[n + 1];
        memcpy(s, _str, _size);
        delete[] _str;
        _str = s;
        _capacity = n;
      }
    }

       增删这里就实现这些成员函数。

       1、push_back  、append 、operator+=

append重载比较多,这里就实现其中的几个。

    //扩容
    void reserve(size_t n)
    {
      if (n > _capacity)
      {
        char* s = new char[n + 1];
        memcpy(s, _str, _size);
        delete[] _str;
        _str = s;
        _capacity = n;
      }
    }
 
    //增
    void push_back(char c)
    {
      if (_size >= _capacity)
      {
        reserve((_capacity == 0) ? 4 : 2 * _capacity);
      }
      _str[_size] = c;
      _size++;
      _str[_size] = '\0';
    }
    void append(const string& str)
    {
      size_t n = _size + str._size;
      if (n > _capacity)
      {
        reserve(n);
      }
      for (int i = 0; i < str._size; i++)
      {
        _str[_size + i] = str._str[i];
      }
      _size += str._size;
      _str[_size] = '\0';
    }
    void append(const char* s)
    {
      size_t len = strlen(s);
      int n = _size + len;
      if (n > _capacity)
      {
        reserve(n);
      }
      for (int i = 0; i < len; i++)
      {
        _str[_size + i] = s[i];
      }
      _size = n;
      _str[_size] = '\0';
    }
    void append(size_t n, char c)
    {
      if (_size + n > _capacity)
      {
        reserve(_size + n);
      }
      for (int i = 0; i < n; i++)
      {
        _str[_size + i] = c;
      }
      _size += n;
      _str[_size] = '\0';
    }
    string& operator+=(const string& str)
    {
      this->append(str);
      return *this;
    }
    string& operator+=(const char* s)
    {
      this->append(s);
      return *this;
    }
    string& operator+=(char c)
    {
      this->push_back(c);
      return *this;
    }

【C++】—— string模拟实现(二)https://developer.aliyun.com/article/1621433

相关文章
|
6天前
|
C++ 容器
|
6天前
|
C++ 容器
|
6天前
|
存储 C++ 容器
|
9天前
|
安全 C语言 C++
【C++篇】探寻C++ STL之美:从string类的基础到高级操作的全面解析
【C++篇】探寻C++ STL之美:从string类的基础到高级操作的全面解析
27 4
|
9天前
|
存储 编译器 程序员
【C++篇】手撕 C++ string 类:从零实现到深入剖析的模拟之路
【C++篇】手撕 C++ string 类:从零实现到深入剖析的模拟之路
41 2
|
10天前
|
编译器 C语言 C++
【C++】C++ STL 探索:String的使用与理解(三)
【C++】C++ STL 探索:String的使用与理解
|
10天前
|
存储 编译器 C++
【C++】C++ STL 探索:String的使用与理解(二)
【C++】C++ STL 探索:String的使用与理解
|
10天前
|
编译器 C语言 C++
【C++】C++ STL 探索:String的使用与理解(一)
【C++】C++ STL 探索:String的使用与理解
|
1天前
|
C语言 C++
深度剖析C++string(中)
深度剖析C++string(中)
5 0
|
1天前
|
存储 编译器 程序员
深度剖析C++string(上篇)(2)
深度剖析C++string(上篇)(2)
5 0