• string类的模拟实现


    目录

    一、浅拷贝、深拷贝

     二、传统版本写法的String类

    三、现代版本写法的String类

    四、String类的模拟实现


    一、浅拷贝、深拷贝

    构造

    1. //构造函数
    2. String(const char* str = "")
    3. {
    4. if (nullptr == str)
    5. {
    6. assert(false);
    7. return;
    8. }
    9. _str = new char[strlen(str) + 1];
    10. strcpy(_str, str);
    11. }

    析构

    1. //析构函数
    2. ~String()
    3. {
    4. if (_str)
    5. {
    6. delete[] _str;
    7. _str = nullptr;
    8. }
    9. }

    代码展示:

    1. #define _CRT_SECURE_NO_WARNINGS
    2. #include<iostream>
    3. using namespace std;
    4. #include<string>
    5. #include<assert.h>
    6. //构造
    7. //拷贝构造
    8. //赋值运算符重载
    9. //析构函数
    10. class String
    11. {
    12. public:
    13. //构造函数
    14. String(const char* str = "")
    15. {
    16. if (nullptr == str)
    17. {
    18. assert(false);
    19. return;
    20. }
    21. _str = new char[strlen(str) + 1];
    22. strcpy(_str, str);
    23. }
    24. //析构函数
    25. ~String()
    26. {
    27. if (_str)
    28. {
    29. delete[] _str;
    30. _str = nullptr;
    31. }
    32. }
    33. private:
    34. char* _str;
    35. };
    36. void TestString()
    37. {
    38. String s1("hello sunlang!");
    39. String s2(s1);
    40. cout << s1 << endl;
    41. cout << s2 << endl;
    42. }
    43. int main()
    44. {
    45. TestString();
    46. return 0;
    47. }

     浅拷贝:编译器合成默认的拷贝构造,导致s1,s2共用同一块内存空间,在释放时同一块空间被释放多次而引起程序崩溃。

    深拷贝每个对象都有一份独立的资源涉及到资源的管理,其拷贝构造函数、赋值运算符重载以及析构函数必须要显示给出

     二、传统版本写法的String类

    1. //传统版本写法的String
    2. class String
    3. {
    4. public:
    5. //构造
    6. String(const char* str = "")
    7. {
    8. if (nullptr == str)
    9. {
    10. assert(false);
    11. return;
    12. }
    13. _str = new char[strlen(str) + 1];
    14. strcpy(_str, str);
    15. }
    16. //拷贝构造
    17. String(const String& s)
    18. :_str(new char[strlen(s._str) + 1])
    19. {
    20. strcpy(_str, s._str);
    21. }
    22. //赋值重载
    23. String& operator=(const String& s)
    24. {
    25. if (this != &s)
    26. {
    27. char* pStr = new char[strlen(s._str) + 1];
    28. strcpy(pStr, s._str);
    29. delete[] _str;
    30. _str = pStr;
    31. }
    32. return *this;
    33. }
    34. //析构
    35. ~String()
    36. {
    37. if (_str)
    38. {
    39. delete[] _str;
    40. _str = nullptr;
    41. }
    42. }
    43. private:
    44. char* _str;
    45. };

    三、现代版本写法的String类

    1. #define _CRT_SECURE_NO_WARNINGS
    2. #include<iostream>
    3. #include<string>
    4. #include<assert.h>
    5. using namespace std;
    6. class String
    7. {
    8. public:
    9. //构造
    10. String(const char* str = "")
    11. {
    12. if (nullptr == str)
    13. {
    14. assert(false);
    15. return;
    16. }
    17. _str = new char[strlen(str) + 1];
    18. strcpy(_str, str);
    19. }
    20. //拷贝构造
    21. String(const String& s)
    22. :_str(nullptr)
    23. {
    24. String strTmp(s._str);
    25. swap(_str, strTmp._str);
    26. }
    27. //赋值重载
    28. String& operator=(String s)
    29. {
    30. swap(_str, s._str);
    31. return *this;
    32. }
    33. ~String()
    34. {
    35. if (_str)
    36. {
    37. delete[] _str;
    38. _str = nullptr;
    39. }
    40. }
    41. private:
    42. char* _str;
    43. };

    四、String类的模拟实现

    1. #define _CRT_SECURE_NO_WARNINGS
    2. #include<iostream>
    3. using namespace std;
    4. #include<assert.h>
    5. namespace sunlang
    6. {
    7. class string
    8. {
    9. public:
    10. typedef char* iterator;
    11. public:
    12. //构造
    13. string(const char* str = "")
    14. {
    15. _size = strlen(str);
    16. _capacity = _size;
    17. _str = new char[_capacity + 1];
    18. strcpy(_str, str);
    19. }
    20. //拷贝构造
    21. string(const string& s)
    22. :_str(nullptr)
    23. , _size(0)
    24. , _capacity(0)
    25. {
    26. string tmp(s._str);
    27. this->swap(tmp);
    28. }
    29. //赋值重载
    30. string& operator=(string s)
    31. {
    32. this->swap(s);
    33. return *this;
    34. }
    35. //析构
    36. ~string()
    37. {
    38. if (_str)
    39. {
    40. delete[] _str;
    41. _str = nullptr;
    42. }
    43. }
    44. //iterator
    45. iterator begin()
    46. {
    47. return _str;
    48. }
    49. iterator end()
    50. {
    51. return _str + _size;
    52. }
    53. //modify
    54. void push_back(char c)
    55. {
    56. if (_size == _capacity)
    57. {
    58. reverse(_capacity * 2);
    59. }
    60. _str[_size++] = c;
    61. _str[_size] = '\0';
    62. }
    63. string& operator+=(char c)
    64. {
    65. push_back(c);
    66. return *this;
    67. }
    68. void clear()
    69. {
    70. _size = 0;
    71. _str[_size] = '\0';
    72. }
    73. void swap(string& s)
    74. {
    75. std::swap(_str, s._str);
    76. std::swap(_size, s._size);
    77. std::swap(_capacity, s._capacity);
    78. }
    79. const char* c_str()const
    80. {
    81. return _str;
    82. }
    83. //capacity
    84. size_t size()const
    85. {
    86. return _size;
    87. }
    88. size_t capacity()const
    89. {
    90. return _capacity;
    91. }
    92. bool empty()const
    93. {
    94. return 0 == _size;
    95. }
    96. void resize(size_t newSize, char c = '\0')
    97. {
    98. if (newSize > _size)
    99. {
    100. if (newSize > _capacity)
    101. {
    102. reserve(newSize);
    103. }
    104. memset(_str + _size, c, newSize - _size);
    105. }
    106. _size = newSize;
    107. _str[newSize] = '\0';
    108. }
    109. void reverse(size_t newCapacity)
    110. {
    111. if (newCapacity > _capacity)
    112. {
    113. char* str = new char[newCapacity + 1];
    114. strcpy(str, _str);
    115. delete[]_str;
    116. _str = str;
    117. _capacity = newCapacity;
    118. }
    119. }
    120. //access
    121. char& operator[](size_t index)
    122. {
    123. assert(index < _size);
    124. return _str[index];
    125. }
    126. const char& operator[](size_t index)const
    127. {
    128. assert(index < _size);
    129. return _str[index];
    130. }
    131. };
    132. }

  • 相关阅读:
    C++每日面试之struct 和 class
    java毕业设计社区宠物管理与推荐系统
    java基于微信小程序的停车场自动收费管理系统 uniapp 小程序
    JNI 初级接触
    SolidWorks 操作视频 | 流体分析结果演示
    《java开发高频面经总结大合集》你想要的都在这里了
    私藏!资深数据专家SQL效率优化技巧 ⛵
    .Net6 已知问题总结
    基于神经网络匹配度的模拟电路故障诊断
    gin框架和logrus自定义日志输出,使日志输出到终端同时写到文件
  • 原文地址:https://blog.csdn.net/lang_965/article/details/128138526