【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;
    }


相关文章
|
25天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
17天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
4天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
1天前
|
人工智能 Rust Java
10月更文挑战赛火热启动,坚持热爱坚持创作!
开发者社区10月更文挑战,寻找热爱技术内容创作的你,欢迎来创作!
253 12
|
19天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
21天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2579 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
3天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
169 2
|
1天前
|
编译器 C#
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
C#多态概述:通过继承实现的不同对象调用相同的方法,表现出不同的行为
101 65
|
21天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1578 16
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
4天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
257 2