C++:模拟实现string类

简介: C++:模拟实现string类

本篇主要介绍模拟实现string类,string中有相当多的内容,这里实现一些相对用途广泛的场景

先看要实现的内容有哪些:

上图源于cplusplus网站,从中截取了部分内容准备进行模拟实现

首先既然string是一个类,那么首先要把类的这个框架搭建起来,我们把string类这个对象放到命名空间中,这样就不会和std中的类所冲突,一个类起码要有构造函数析构函数成员变量:

namespace My_string
{
  class string
  {
  public:
// Constructor/Destructor
    string(const char* str = "")
      : _size(strlen(str))
      , _capacity(_size)
    {
      _str = new char[_capacity + 1];
      strcpy(_str, str);
    }
    ~string()
    {
      delete[] _str;
    }
    string& operator=(const char* str)
    {
      _size = strlen(str);
      _capacity = _size;
      _str = new char[_capacity + 1];
      strcpy(_str, str);
      return *this;
    }
    string& operator=(const string& str)
    {
      _capacity = str._capacity;
      _size = str._size;
      _str = new char[_capacity + 1];
      strcpy(_str, str._str);
      return *this;
    }
    string& operator=(char c)
    {
      _capacity = 1;
      _size = 1;
      _str = new char[_capacity + 1];
      _str[0] = c;
      return *this;
    }
  private:
    char* _str;
    size_t _size;
    size_t _capacity;
    const static size_t npos;
  };
  const size_t string::npos = -1;
}

至此,string类的大体框架已经搭建完毕了,下面进行string类内部成员函数的完善

Iterator类

begin和end迭代器实现:

从上面库函数中可以看出,这里返回的是迭代器,而我们又知道,实际上迭代器就是指针的作用,因此我们这里就用指针来模拟实现迭代器的作用

// Iterator
typedef char* iterator;
typedef const char* const_iterator;
iterator begin()
{
  return _str;
}
const_iterator begin() const
{
  return _str;
}
iterator end()
{
  return _str + _size;
}
const_iterator end() const
{
  return _str + _size;
}

capacity类

实现的函数主要有:

// Capacity
size_t size()
{
  return _size;
}
size_t size() const
{
  return _size;
}
size_t lenth()
{
  return _size;
}
void resize(size_t n, char c = '\0')
{
  ;
}
size_t capacity()
{
  return _capacity;
}
void reserve(size_t n)
{
  if (n > _capacity)
  {
    char* tmp = new char[n + 1];
    strcpy(tmp, _str);
    delete[] _str;
    _str = tmp;
    _capacity = n;
  }
}
void clear()
{
  memset(_str, '\0', _size);
  _size = 0;
}
bool empty() const
{
  if (_size == 0)
  {
    return true;
  }
  return false;
}

Element access 类

实现的函数主要有

// Element access
char& operator[](size_t pos)
{
  assert(pos < _size);
  return _str[pos];
}
const char& operator[](size_t pos) const
{
  assert(pos < _size);
  return _str[pos];
}
char& at(size_t pos)
{
  assert(pos < _size);
  return _str[pos];
}
const char& at(size_t pos) const
{
  assert(pos < _size);
  return _str[pos];
}
char& back()
{
  return _str[_size - 1];
}
const char& back() const
{
  assert(_size - 1 >= 0);
  return _str[_size - 1];
}
char& front()
{
  assert(_size - 1 >= 0);
  return _str[0];
}
const char& front() const
{
  return _str[0];
}

Modifiers类

实现的函数主要有

//Modifiers
string operator+(const char* str)
{
  size_t len = strlen(str);
  reserve(len + _size);
  strcpy(_str + _size, str);
  string s1;
  s1 = *this;
  return s1;
}
string operator + (const string& str)
{
  size_t len = strlen(str._str);
  reserve(len + _size);
  strcpy(_str + _size, str._str);
  string s1;
  s1 = *this;
  return s1;
}
string operator + (char str)
{
  if (_size == _capacity)
  {
    reserve(_size + 1);
  }
  _str[_size++] = str;
  string s1;
  s1 = *this;
  return s1;
}
string& operator+=(const char* str)
{
  append(str);
  return *this;
}
string& operator += (const string& str)
{
  append(str);
  return *this;
}
string& operator += (char str)
{
  push_back(str);
  return *this;
}
void append(const string& str)
{
  size_t len = strlen(str._str);
  if (_size + len > _capacity)
  {
    reserve(_size + len);
  }
  strcpy(_str + _size, str._str);
  _size += len;
}
void append(const char* str)
{
  size_t len = strlen(str);
  if (_size + len > _capacity)
  {
    reserve(_size + len);
  }
  strcpy(_str + _size, str);
  _size += len;
}
void push_back(char c)
{
  if (_size == _capacity)
  {
    reserve(_capacity == 0 ? 4 : _capacity * 2);
  }
  _str[_size++] = c;
  _str[_size] = '\0';
}
string& insert(size_t pos, char ch)
{
  assert(pos <= _size);
  if (_size == _capacity)
  {
    reserve(_capacity == 0 ? 4 : _capacity * 2);
  }
  size_t end = _size + 1;
  while (end > pos)
  {
    _str[end] = _str[end - 1];
    --end;
  }
  _str[pos] = ch;
  _size++;
  return *this;
}
string& insert(size_t pos, const char* str)
{
  assert(pos <= _size);
  size_t len = strlen(str);
  if (_size + len == _capacity)
  {
    reserve(_capacity == 0 ? 4 : _capacity * 2);
  }
  size_t end = _size + len;
  while (end > pos + len - 1)
  {
    _str[end] = _str[end - len];
    --end;
  }
  memmove(_str + pos, str, len);
  _size += len;
}
string& insert(size_t pos, const string& str)
{
  assert(pos <= _size);
  size_t len = strlen(str._str);
  if (_size + len == _capacity)
  {
    reserve(_capacity == 0 ? 4 : _capacity * 2);
  }
  size_t end = _size + len;
  while (end > pos + len - 1)
  {
    _str[end] = _str[end - len];
    --end;
  }
  memmove(_str + pos, str._str, len);
  _size += len;
}
string& erase(size_t pos, size_t  len = npos)
{
  if (len == -1)
  {
    size_t n = pos;
    while (n < _size)
    {
      _str[n] = '\0';
      n++;
    }
    _size = pos - 1;
  }
  else
  {
    assert(pos + len < _size);
    size_t left = pos + len - 1;
    size_t end = _size + 1;
    while (left < end)
    {
      _str[pos] = _str[left];
      pos++;
      left++;
    }
    _size = _size - len;
  }
  return *this;
}
void swap(string& s)
{
  string tmp = s;
  s = *this;
  *this = tmp;
}
void pop_back()
{
  _str[_size - 1] = '\0';
  _size--;
}

String operations类

实现的函数主要有:

char* c_str()
{
  return _str;
}
size_t find(const string& str, size_t pos = 0) const
{
  int begin = 0;
  int end = (int)_size;
  while (begin < end)
  {
    size_t len = strlen(str._str);
    if (_str[begin] == str._str[0])
    {
      int left = begin;
      int res = 1;
      for (int i = 0; i < len; i++)
      {
        if (_str[left] != _str[i])
        {
          break;
        }
        res++;
        left++;
      }
      if (res == len)
      {
        return begin;
      }
    }
    else
    {
      begin++;
    }
  }
  return npos;
}
string substr(size_t pos = 0, size_t len = npos) const
{
  string s1;
  if (len == npos)
  {
    while (_str[pos] != '\0')
    {
      s1 += _str[pos];
      pos++;
    }
  }
  else
  {
    for (int i = 0; i < len; i++)
    {
      s1 += _str[pos];
      pos++;
    }
  }
  return s1;
}
string operator+ (const string& str) const
{
  return *this + str;
}
bool operator== (const string& str) const
{
  return strcmp(_str, str._str) == 0;
}
bool operator!= (const string& str) const
{
  return !(*this == str);
}
bool operator< (const string& str) const
{
  return strcmp(_str, str._str) < 0;
}
bool operator> (const string& str) const
{
  return strcmp(_str, str._str) > 0;
}
bool operator<= (const string& str) const
{
  return (*this < str) || (*this == str);
}
bool operator>= (const string& str) const
{
  return (*this > str) || (*this == str);
}

类外成员函数

实现的函数主要有:

std::ostream& operator<<(std::ostream& out, const string& s)
{
  for (size_t i = 0; i < s.size(); i++)
  {
    out << s[i];
  }
  return out;
}
std::istream& operator>>(std::istream& in, string& s)
{
  s.clear();
  char ch;
  ch = in.get();
  s.reserve(128);
  while (ch != ' ' && ch != '\n')
  {
    s += ch;
    ch = in.get();
  }
  return in;
}

头文件总括

#include <iostream>
#include <assert.h>
namespace My_string
{
  typedef char* iterator;
  typedef const char* const_iterator;
  class string
  {
  public:
    // Constructor/Destructor
    string(const char* str = "")
      : _size(strlen(str))
      , _capacity(_size)
    {
      _str = new char[_capacity + 1];
      strcpy(_str, str);
    }
    ~string()
    {
      delete[] _str;
    }
    string& operator=(const char* str)
    {
      _size = strlen(str);
      _capacity = _size;
      _str = new char[_capacity + 1];
      strcpy(_str, str);
      return *this;
    }
    string& operator=(const string& str)
    {
      _capacity = str._capacity;
      _size = str._size;
      _str = new char[_capacity + 1];
      strcpy(_str, str._str);
      return *this;
    }
    string& operator=(char c)
    {
      _capacity = 1;
      _size = 1;
      _str = new char[_capacity + 1];
      _str[0] = c;
      return *this;
    }
    // Iterator
    iterator begin()
    {
      return _str;
    }
    const_iterator begin() const
    {
      return _str;
    }
    iterator end()
    {
      return _str + _size;
    }
    const_iterator end() const
    {
      return _str + _size;
    }
    // Capacity
    size_t size()
    {
      return _size;
    }
    size_t size() const
    {
      return _size;
    }
    size_t lenth()
    {
      return _size;
    }
    void resize(size_t n, char c = '\0')
    {
      ;
    }
    size_t capacity()
    {
      return _capacity;
    }
    void reserve(size_t n)
    {
      if (n > _capacity)
      {
        char* tmp = new char[n + 1];
        strcpy(tmp, _str);
        delete[] _str;
        _str = tmp;
        _capacity = n;
      }
    }
    void clear()
    {
      memset(_str, '\0', _size);
      _size = 0;
    }
    bool empty() const
    {
      if (_size == 0)
      {
        return true;
      }
      return false;
    }
    // Element access
    char& operator[](size_t pos)
    {
      assert(pos < _size);
      return _str[pos];
    }
    const char& operator[](size_t pos) const
    {
      assert(pos < _size);
      return _str[pos];
    }
    char& at(size_t pos)
    {
      assert(pos < _size);
      return _str[pos];
    }
    const char& at(size_t pos) const
    {
      assert(pos < _size);
      return _str[pos];
    }
    char& back()
    {
      return _str[_size - 1];
    }
    const char& back() const
    {
      assert(_size - 1 >= 0);
      return _str[_size - 1];
    }
    char& front()
    {
      assert(_size - 1 >= 0);
      return _str[0];
    }
    const char& front() const
    {
      return _str[0];
    }
    //Modifiers
    string operator+(const char* str)
    {
      size_t len = strlen(str);
      reserve(len + _size);
      strcpy(_str + _size, str);
      string s1;
      s1 = *this;
      return s1;
    }
    string operator + (const string& str)
    {
      size_t len = strlen(str._str);
      reserve(len + _size);
      strcpy(_str + _size, str._str);
      string s1;
      s1 = *this;
      return s1;
    }
    string operator + (char str)
    {
      if (_size == _capacity)
      {
        reserve(_size + 1);
      }
      _str[_size++] = str;
      string s1;
      s1 = *this;
      return s1;
    }
    string& operator+=(const char* str)
    {
      append(str);
      return *this;
    }
    string& operator += (const string& str)
    {
      append(str);
      return *this;
    }
    string& operator += (char str)
    {
      push_back(str);
      return *this;
    }
    void append(const string& str)
    {
      size_t len = strlen(str._str);
      if (_size + len > _capacity)
      {
        reserve(_size + len);
      }
      strcpy(_str + _size, str._str);
      _size += len;
    }
    void append(const char* str)
    {
      size_t len = strlen(str);
      if (_size + len > _capacity)
      {
        reserve(_size + len);
      }
      strcpy(_str + _size, str);
      _size += len;
    }
    void push_back(char c)
    {
      if (_size == _capacity)
      {
        reserve(_capacity == 0 ? 4 : _capacity * 2);
      }
      _str[_size++] = c;
      _str[_size] = '\0';
    }
    string& insert(size_t pos, char ch)
    {
      assert(pos <= _size);
      if (_size == _capacity)
      {
        reserve(_capacity == 0 ? 4 : _capacity * 2);
      }
      size_t end = _size + 1;
      while (end > pos)
      {
        _str[end] = _str[end - 1];
        --end;
      }
      _str[pos] = ch;
      _size++;
      return *this;
    }
    string& insert(size_t pos, const char* str)
    {
      assert(pos <= _size);
      size_t len = strlen(str);
      if (_size + len == _capacity)
      {
        reserve(_capacity == 0 ? 4 : _capacity * 2);
      }
      size_t end = _size + len;
      while (end > pos + len - 1)
      {
        _str[end] = _str[end - len];
        --end;
      }
      memmove(_str + pos, str, len);
      _size += len;
    }
    string& insert(size_t pos, const string& str)
    {
      assert(pos <= _size);
      size_t len = strlen(str._str);
      if (_size + len == _capacity)
      {
        reserve(_capacity == 0 ? 4 : _capacity * 2);
      }
      size_t end = _size + len;
      while (end > pos + len - 1)
      {
        _str[end] = _str[end - len];
        --end;
      }
      memmove(_str + pos, str._str, len);
      _size += len;
    }
    string& erase(size_t pos, size_t  len = npos)
    {
      if (len == -1)
      {
        size_t n = pos;
        while (n < _size)
        {
          _str[n] = '\0';
          n++;
        }
        _size = pos - 1;
      }
      else
      {
        assert(pos + len < _size);
        size_t left = pos + len - 1;
        size_t end = _size + 1;
        while (left < end)
        {
          _str[pos] = _str[left];
          pos++;
          left++;
        }
        _size = _size - len;
      }
      return *this;
    }
    void swap(string& s)
    {
      string tmp = s;
      s = *this;
      *this = tmp;
    }
    void pop_back()
    {
      _str[_size - 1] = '\0';
      _size--;
    }
    // String operations
    char* c_str()
    {
      return _str;
    }
    size_t find(const string& str, size_t pos = 0) const
    {
      int begin = 0;
      int end = (int)_size;
      while (begin < end)
      {
        size_t len = strlen(str._str);
        if (_str[begin] == str._str[0])
        {
          int left = begin;
          int res = 1;
          for (int i = 0; i < len; i++)
          {
            if (_str[left] != _str[i])
            {
              break;
            }
            res++;
            left++;
          }
          if (res == len)
          {
            return begin;
          }
        }
        else
        {
          begin++;
        }
      }
      return npos;
    }
    string substr(size_t pos = 0, size_t len = npos) const
    {
      string s1;
      if (len == npos)
      {
        while (_str[pos] != '\0')
        {
          s1 += _str[pos];
          pos++;
        }
      }
      else
      {
        for (int i = 0; i < len; i++)
        {
          s1 += _str[pos];
          pos++;
        }
      }
      return s1;
    }
    string operator+ (const string& str) const
    {
      return *this + str;
    }
    bool operator== (const string& str) const
    {
      return strcmp(_str, str._str) == 0;
    }
    bool operator!= (const string& str) const
    {
      return !(*this == str);
    }
    bool operator< (const string& str) const
    {
      return strcmp(_str, str._str) < 0;
    }
    bool operator> (const string& str) const
    {
      return strcmp(_str, str._str) > 0;
    }
    bool operator<= (const string& str) const
    {
      return (*this < str) || (*this == str);
    }
    bool operator>= (const string& str) const
    {
      return (*this > str) || (*this == str);
    }
  private:
    char* _str;
    size_t _size;
    size_t _capacity;
    const static size_t npos;
  };
  const size_t string::npos = -1;
  std::ostream& operator<<(std::ostream& out, const string& s)
  {
    for (size_t i = 0; i < s.size(); i++)
    {
      out << s[i];
    }
    return out;
  }
  std::istream& operator>>(std::istream& in, string& s)
  {
    s.clear();
    char ch;
    ch = in.get();
    s.reserve(128);
    while (ch != ' ' && ch != '\n')
    {
      s += ch;
      ch = in.get();
    }
    return in;
  }
}


相关文章
|
1月前
|
编解码 Java 开发者
Java String类的关键方法总结
以上总结了Java `String` 类最常见和重要功能性方法。每种操作都对应着日常编程任务,并且理解每种操作如何影响及处理 `Strings` 对于任何使用 Java 的开发者来说都至关重要。
262 5
|
9月前
|
存储 安全 C语言
C++ String揭秘:写高效代码的关键
在C++编程中,字符串操作是不可避免的一部分。从简单的字符串拼接到复杂的文本处理,C++的string类为开发者提供了一种更高效、灵活且安全的方式来管理和操作字符串。本文将从基础操作入手,逐步揭开C++ string类的奥秘,帮助你深入理解其内部机制,并学会如何在实际开发中充分发挥其性能和优势。
|
9月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
5月前
|
对象存储 C++ 容器
c++的string一键介绍
这篇文章旨在帮助读者回忆如何使用string,并提醒注意事项。它不是一篇详细的功能介绍,而是一篇润色文章。先展示重载函数,如果该函数一笔不可带过,就先展示英文原档(附带翻译),最后展示代码实现与举例可以直接去看英文文档,也可以看本篇文章,但是更建议去看英文原档。那么废话少说直接开始进行挨个介绍。
119 3
|
5月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
157 0
|
5月前
|
存储 编译器 C语言
关于string的‘\0‘与string,vector构造特点,反迭代器与迭代器类等的讨论
你真的了解string的'\0'么?你知道创建一个string a("abcddddddddddddddddddddddddd", 16);这样的string对象要创建多少个对象么?你知道string与vector进行扩容时进行了怎么的操作么?你知道怎么求Vector 最大 最小值 索引 位置么?
142 0
|
5月前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
249 0
|
7月前
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
287 12
|
8月前
|
设计模式 安全 C++
【C++进阶】特殊类设计 && 单例模式
通过对特殊类设计和单例模式的深入探讨,我们可以更好地设计和实现复杂的C++程序。特殊类设计提高了代码的安全性和可维护性,而单例模式则确保类的唯一实例性和全局访问性。理解并掌握这些高级设计技巧,对于提升C++编程水平至关重要。
173 16
|
8月前
|
缓存 安全 Java
《从头开始学java,一天一个知识点》之:字符串处理:String类的核心API
🌱 **《字符串处理:String类的核心API》一分钟速通!** 本文快速介绍Java中String类的3个高频API:`substring`、`indexOf`和`split`,并通过代码示例展示其用法。重点提示:`substring`的结束索引不包含该位置,`split`支持正则表达式。进一步探讨了String不可变性的高效设计原理及企业级编码规范,如避免使用`new String()`、拼接时使用`StringBuilder`等。最后通过互动解密游戏帮助读者巩固知识。 (上一篇:《多维数组与常见操作》 | 下一篇预告:《输入与输出:Scanner与System类》)
229 11