提示信息

C++ 中 string 类模拟实现:从零开始的旅程

韦鑫希 已关注

模拟实现 C++ 中的 string 类是一个复杂且有趣的项目。这可以帮助你深入理解字符串操作的基础,内存管理,以及一些面向对象编程的概念。在实现过程中,我们需要从基本的内存管理、字符串操作方法和运算符重载等方面入手。下面是一个简化实现的过程:

基本结构

  1. 成员变量

    • char* data;:用于存储字符串。
    • size_t size;:存储字符串长度。
    • size_t capacity;:存储当前分配的内存大小。
  2. 构造函数

    • 默认构造函数。
    • 通过 const char* 初始化。
    • 复制构造函数。
    • 移动构造函数。
  3. 析构函数

    • 释放分配的内存。
  4. 成员函数

    • 大小相关:size()capacity()empty()
    • 访问字符:重载 operator[]at()
    • 修改字符串:append()clear()resize()
    • 内存管理:reserve()
  5. 运算符重载

    • 赋值运算符。
    • 加号运算符 + 用于连接字符串。
    • 比较运算符。

实现步骤

  1. #include <iostream>
  2. #include <cstring>
  3. class MyString {
  4. private:
  5. char* data;
  6. size_t size;
  7. size_t capacity;
  8. void initFromCStr(const char* cstr) {
  9. size = std::strlen(cstr);
  10. capacity = size;
  11. data = new char[capacity + 1];
  12. std::strcpy(data, cstr);
  13. }
  14. public:
  15. // 默认构造函数
  16. MyString() : data(new char[1]), size(0), capacity(0) {
  17. data[0] = '\0';
  18. }
  19. // 通过 const char* 初始化
  20. MyString(const char* cstr) {
  21. initFromCStr(cstr);
  22. }
  23. // 复制构造函数
  24. MyString(const MyString& other) {
  25. initFromCStr(other.data);
  26. }
  27. // 移动构造函数
  28. MyString(MyString&& other) noexcept : data(other.data), size(other.size), capacity(other.capacity) {
  29. other.data = nullptr;
  30. other.size = 0;
  31. other.capacity = 0;
  32. }
  33. // 析构函数
  34. ~MyString() {
  35. delete[] data;
  36. }
  37. // 赋值运算符
  38. MyString& operator=(const MyString& other) {
  39. if (this != &other) {
  40. delete[] data;
  41. initFromCStr(other.data);
  42. }
  43. return *this;
  44. }
  45. // 移动赋值运算符
  46. MyString& operator=(MyString&& other) noexcept {
  47. if (this != &other) {
  48. delete[] data;
  49. data = other.data;
  50. size = other.size;
  51. capacity = other.capacity;
  52. other.data = nullptr;
  53. other.size = 0;
  54. other.capacity = 0;
  55. }
  56. return *this;
  57. }
  58. // 大小和容量
  59. size_t getSize() const { return size; }
  60. size_t getCapacity() const { return capacity; }
  61. bool empty() const { return size == 0; }
  62. // 访问字符
  63. char& operator[](size_t idx) { return data[idx]; }
  64. const char& operator[](size_t idx) const { return data[idx]; }
  65. char& at(size_t idx) {
  66. if (idx >= size) throw std::out_of_range("Index out of range");
  67. return data[idx];
  68. }
  69. // 修改字符串
  70. void clear() {
  71. delete[] data;
  72. data = new char[1];
  73. data[0] = '\0';
  74. size = 0;
  75. capacity = 0;
  76. }
  77. void append(const MyString& other) {
  78. size_t new_size = size + other.size;
  79. if (new_size > capacity) {
  80. reserve(new_size);
  81. }
  82. std::strcat(data, other.data);
  83. size = new_size;
  84. }
  85. void reserve(size_t new_capacity) {
  86. if (new_capacity > capacity) {
  87. char* new_data = new char[new_capacity + 1];
  88. std::strcpy(new_data, data);
  89. delete[] data;
  90. data = new_data;
  91. capacity = new_capacity;
  92. }
  93. }
  94. // 运算符重载
  95. MyString operator+(const MyString& other) const {
  96. MyString result(*this);
  97. result.append(other);
  98. return result;
  99. }
  100. };
  101. int main() {
  102. MyString str1("Hello");
  103. MyString str2(" World!");
  104. MyString str3 = str1 + str2;
  105. std::cout << str3[0] << str3[1] << str3[2] << str3[3] << str3[4] << std::endl; // Prints: Hello
  106. return 0;
  107. }

说明

  1. 内存管理:通过使用 newdelete,管理字符串的分配和释放。
  2. 字符串操作:实现了基本的字符串连接和访问,这也可以扩展到更多的字符串操作。
  3. 异常处理at() 方法演示了如何处理异常,如访问越界。
  4. 对象语义:实现复制和移动语义,以确保对象的高效管理和使用。

这个实现仅仅是一个简单的示例,实际的 std::string 类要复杂得多,包括更多的优化和特性。你可以在此基础上扩展其他功能,如输入输出运算符重载、更多的字符串操作、改进的内存管理等。

    遇到难题? "AI大模型GPT4.0、GPT" 是你的私人解答专家! 点击按钮去提问......
韦鑫希 关注 已关注

最近一次登录:2024-11-21 01:30:01   

暂时还没有签名,请关注我或评论我的文章
×
免费图表工具,画流程图、架构图