• string cow方法实现


    1. #include
    2. #include
    3. using std::cout;
    4. using std::endl;
    5. class String
    6. {
    7. public:
    8. //String s1;
    9. String()
    10. : _pstr(new char[5]() + 4)//1 '\0' 2-5 RefCount int
    11. {
    12. cout << "String()" << endl;
    13. initRefCount();
    14. }
    15. //String s1("hello");
    16. String(const char *pstr)
    17. : _pstr(new char[strlen(pstr) + 5]() + 4)
    18. {
    19. cout << "String(const char *)" << endl;
    20. strcpy(_pstr, pstr);
    21. initRefCount();
    22. }
    23. //String s2(s1);
    24. String(const String &rhs)
    25. : _pstr(rhs._pstr)//浅拷贝
    26. {
    27. cout << "String(const String &)" << endl;
    28. increaseRefCount();
    29. }
    30. //String s3("world");
    31. //s3 = s1
    32. String &operator=(const String &rhs)
    33. {
    34. if(this != &rhs)//1、自复制
    35. {
    36. //2、释放左操作
    37. release();
    38. //3、深拷贝(浅拷贝)
    39. _pstr = rhs._pstr;
    40. increaseRefCount();
    41. }
    42. return *this;//4、返回*this
    43. }
    44. private:
    45. class CharProxy
    46. {
    47. public:
    48. CharProxy(String &self, size_t idx)
    49. : _self(self)
    50. , _idx(idx)
    51. {
    52. }
    53. char &operator=(const char &ch);//写操作
    54. friend std::ostream &operator<<(std::ostream &os, const CharProxy &rhs);
    55. private:
    56. String &_self;//此时String是不完整类型
    57. size_t _idx;
    58. };
    59. public:
    60. //下边访问运算符
    61. //s3[0] = 'H'
    62. //cout <<"s1[0] = " << s1[0] << endl;
    63. CharProxy operator[](size_t idx)//String *this
    64. {
    65. return CharProxy(*this, idx);
    66. }
    67. #if 0
    68. char &operator[](size_t idx)
    69. {
    70. if(idx < this->size())
    71. {
    72. if(getRefCount() > 1)//考虑共享问题
    73. {
    74. char *ptmp = new char[size() + 5]() + 4;
    75. strcpy(ptmp, _pstr);
    76. decreaseRefCount();
    77. _pstr = ptmp;
    78. initRefCount();
    79. }
    80. return _pstr[idx];
    81. }
    82. else
    83. {
    84. static char charnull = '\0';
    85. return charnull;
    86. }
    87. }
    88. #endif
    89. //s3
    90. ~String()
    91. {
    92. cout << "~String()" << endl;
    93. release();
    94. }
    95. public:
    96. const char *c_str() const
    97. {
    98. return _pstr;
    99. }
    100. int getRefCount() const
    101. {
    102. return *(int *)(_pstr - 4);
    103. }
    104. private:
    105. size_t size() const
    106. {
    107. return strlen(_pstr);
    108. }
    109. void initRefCount()
    110. {
    111. *(int *)(_pstr - 4) = 1;
    112. }
    113. void increaseRefCount()
    114. {
    115. ++*(int *)(_pstr - 4);
    116. }
    117. void decreaseRefCount()
    118. {
    119. --*(int *)(_pstr - 4);
    120. }
    121. void release()
    122. {
    123. decreaseRefCount();
    124. if(0 == getRefCount())
    125. {
    126. delete [] (_pstr - 4);
    127. }
    128. }
    129. friend std::ostream &operator<<(std::ostream &os, const String &rhs);
    130. friend std::ostream &operator<<(std::ostream &os, const String::CharProxy &rhs);
    131. private:
    132. char *_pstr;
    133. };
    134. std::ostream &operator<<(std::ostream &os, const String &rhs)
    135. {
    136. if(rhs._pstr)
    137. {
    138. os << rhs._pstr;
    139. }
    140. return os;
    141. }
    142. //CharProxy里面的函数
    143. //s3[0] = 'H'
    144. char &String::CharProxy::operator=(const char &ch)
    145. {
    146. if(_idx < _self.size())
    147. {
    148. if(_self.getRefCount() > 1)//考虑共享问题
    149. {
    150. char *ptmp = new char[_self.size() + 5]() + 4;
    151. strcpy(ptmp, _self._pstr);
    152. _self.decreaseRefCount();
    153. _self._pstr = ptmp;
    154. _self.initRefCount();
    155. }
    156. _self._pstr[_idx] = ch;//真正的赋值操作
    157. return _self._pstr[_idx];
    158. }
    159. else
    160. {
    161. static char charnull = '\0';
    162. return charnull;
    163. }
    164. }
    165. //双友元的设置
    166. std::ostream &operator<<(std::ostream &os, const String::CharProxy &rhs)
    167. {
    168. os << rhs._self._pstr[rhs._idx];
    169. return os;
    170. }
    171. void test()
    172. {
    173. String s1("hello");
    174. String s2(s1);
    175. cout << "s1 = " << s1 << endl;
    176. cout << "s2 = " << s2 << endl;
    177. cout << "s1.getRefCount() = " << s1.getRefCount() << endl;
    178. cout << "s2.getRefCount() = " << s2.getRefCount() << endl;
    179. printf("s1'address : %p\n", s1.c_str());
    180. printf("s2'address : %p\n", s2.c_str());
    181. cout << endl;
    182. String s3("world");
    183. cout << "s3 = " << s3 << endl;
    184. cout << "s3.getRefCount() = " << s3.getRefCount() << endl;
    185. printf("s3'address : %p\n", s3.c_str());
    186. cout << endl << "使用s3 = s1进行赋值操作" << endl;
    187. s3 = s1;
    188. cout << "s1 = " << s1 << endl;
    189. cout << "s2 = " << s2 << endl;
    190. cout << "s3 = " << s3 << endl;
    191. cout << "s1.getRefCount() = " << s1.getRefCount() << endl;
    192. cout << "s2.getRefCount() = " << s2.getRefCount() << endl;
    193. cout << "s3.getRefCount() = " << s3.getRefCount() << endl;
    194. printf("s1'address : %p\n", s1.c_str());
    195. printf("s2'address : %p\n", s2.c_str());
    196. printf("s3'address : %p\n", s3.c_str());
    197. cout << endl << "对s3[0]执行写操作" << endl;
    198. s3[0] = 'H';//'h' = 'H' char = char// CharProxy = char//"hello"
    199. s3.operator[](0).operator=('H');
    200. cout << "s1 = " << s1 << endl;
    201. cout << "s2 = " << s2 << endl;
    202. cout << "s3 = " << s3 << endl;
    203. cout << "s1.getRefCount() = " << s1.getRefCount() << endl;
    204. cout << "s2.getRefCount() = " << s2.getRefCount() << endl;
    205. cout << "s3.getRefCount() = " << s3.getRefCount() << endl;
    206. printf("s1'address : %p\n", s1.c_str());
    207. printf("s2'address : %p\n", s2.c_str());
    208. printf("s3'address : %p\n", s3.c_str());
    209. cout << endl << "对s1[0]执行读操作" << endl;
    210. cout << "s1[0] = " << s1[0] << endl;//cout << CharProxy//CharProxy -> char
    211. cout << "s1 = " << s1 << endl;
    212. cout << "s2 = " << s2 << endl;
    213. cout << "s3 = " << s3 << endl;
    214. cout << "s1.getRefCount() = " << s1.getRefCount() << endl;
    215. cout << "s2.getRefCount() = " << s2.getRefCount() << endl;
    216. cout << "s3.getRefCount() = " << s3.getRefCount() << endl;
    217. printf("s1'address : %p\n", s1.c_str());
    218. printf("s2'address : %p\n", s2.c_str());
    219. printf("s3'address : %p\n", s3.c_str());
    220. }
    221. int main(int argc, char **argv)
    222. {
    223. test();
    224. return 0;
    225. }
    1. #include
    2. #include
    3. #include
    4. using std::cout;
    5. using std::endl;
    6. using std::vector;
    7. class String
    8. {
    9. public:
    10. String()
    11. // : _pstr(nullptr)//后面操作的时候,需要判空
    12. : _pstr(new char[1]())
    13. {
    14. cout << "String()" << endl;
    15. }
    16. //String s1("hello")
    17. String(const char *pstr)
    18. : _pstr(new char[strlen(pstr) + 1]())
    19. {
    20. cout << "String(const char *)" << endl;
    21. strcpy(_pstr, pstr);
    22. }
    23. //String s2(s1);
    24. String(const String &rhs)
    25. : _pstr(new char[strlen(rhs._pstr) +1]())
    26. {
    27. cout << "String(const String &)" << endl;
    28. strcpy(_pstr, rhs._pstr);
    29. }
    30. ~String()
    31. {
    32. cout << "~String()" << endl;
    33. if(_pstr)
    34. {
    35. delete [] _pstr;
    36. _pstr = nullptr;
    37. }
    38. }
    39. //String s1;
    40. //s1 = s1;
    41. String &operator=(const String &rhs)
    42. {
    43. cout << "String &operator=(const String &)" << endl;
    44. if(this != &rhs)
    45. {
    46. delete [] _pstr;
    47. _pstr = nullptr;
    48. _pstr = new char[strlen(rhs._pstr) + 1]();
    49. strcpy(_pstr, rhs._pstr);
    50. }
    51. return *this;
    52. }
    53. // s1 = "hello";
    54. String &operator=(const char *pstr)
    55. {
    56. cout << "String &operator=(const char *)" << endl;
    57. String tmp(pstr);
    58. *this = tmp;
    59. return *this;
    60. }
    61. //s1 += s2;
    62. String &operator+=(const String &rhs)
    63. {
    64. cout << "String &operator+=(const String &)" <
    65. String tmp;
    66. if(tmp._pstr)
    67. {
    68. delete [] tmp._pstr;//防止内存泄漏
    69. }
    70. tmp._pstr = new char[strlen(_pstr) + 1]();
    71. strcpy(tmp._pstr, _pstr);
    72. delete [] _pstr;
    73. _pstr = nullptr;
    74. _pstr = new char[strlen(rhs._pstr) + strlen(tmp._pstr) + 1]();
    75. strcpy(_pstr, tmp._pstr);
    76. strcat(_pstr, rhs._pstr);
    77. return *this;
    78. }
    79. //s1 += "hello"
    80. String &operator+=(const char *pstr)
    81. {
    82. cout << "String &operator+=(const char *)" << endl;
    83. String tmp(pstr);
    84. *this += tmp;
    85. return *this;
    86. }
    87. //const String s1("helo");
    88. //s1[0]
    89. char &operator[](std::size_t index)//index > = 0
    90. {
    91. if(index < size())
    92. {
    93. return _pstr[index];
    94. }
    95. else
    96. {
    97. static char nullchar = '\0';
    98. return nullchar;
    99. }
    100. }
    101. const char &operator[](std::size_t index) const
    102. {
    103. if(index < size())
    104. {
    105. return _pstr[index];
    106. }
    107. else
    108. {
    109. static char nullchar = '\0';
    110. return nullchar;
    111. }
    112. }
    113. std::size_t size() const
    114. {
    115. return strlen(_pstr);
    116. }
    117. const char* c_str() const
    118. {
    119. return _pstr;
    120. }
    121. friend bool operator==(const String &, const String &);
    122. friend bool operator!=(const String &, const String &);
    123. friend bool operator<(const String &, const String &);
    124. friend bool operator>(const String &, const String &);
    125. friend bool operator<=(const String &, const String &);
    126. friend bool operator>=(const String &, const String &);
    127. friend std::ostream &operator<<(std::ostream &os, const String &s);
    128. friend std::istream &operator>>(std::istream &is, String &s);
    129. private:
    130. char * _pstr;
    131. };
    132. bool operator==(const String &lhs, const String &rhs)
    133. {
    134. return !strcmp(lhs._pstr, rhs._pstr);
    135. }
    136. bool operator!=(const String &lhs, const String &rhs)
    137. {
    138. return strcmp(lhs._pstr, rhs._pstr);
    139. }
    140. bool operator<(const String &lhs, const String &rhs)
    141. {
    142. return strcmp(lhs._pstr, rhs._pstr) < 0;
    143. }
    144. bool operator>(const String &lhs, const String &rhs)
    145. {
    146. return strcmp(lhs._pstr, rhs._pstr) > 0;
    147. }
    148. bool operator<=(const String &lhs, const String &rhs)
    149. {
    150. return strcmp(lhs._pstr, rhs._pstr) <= 0;
    151. }
    152. bool operator>=(const String &lhs, const String &rhs)
    153. {
    154. return strcmp(lhs._pstr, rhs._pstr) >= 0;
    155. }
    156. std::ostream &operator<<(std::ostream &os, const String &rhs)
    157. {
    158. if(rhs._pstr)
    159. {
    160. os << rhs._pstr;
    161. }
    162. return os;
    163. }
    164. //String s1("hello")
    165. //cin >> s1;
    166. std::istream &operator>>(std::istream &is, String &rhs)
    167. {
    168. if(rhs._pstr)
    169. {
    170. delete [] rhs._pstr;
    171. rhs._pstr = nullptr;
    172. }
    173. //动态获取从键盘输入数据的长度
    174. vector<char> buffer;
    175. char ch;
    176. while((ch = is.get()) != '\n')
    177. {
    178. buffer.push_back(ch);
    179. }
    180. rhs._pstr = new char[buffer.size() + 1]();
    181. strncpy(rhs._pstr, &buffer[0], buffer.size());
    182. return is;
    183. }
    184. String operator+(const String &lhs, const String &rhs)
    185. {
    186. cout << "String operator+(const String &, const String &)" << endl;
    187. String tmp(lhs);
    188. tmp += rhs;
    189. return tmp;
    190. }
    191. String operator+(const String &lhs, const char *pstr)
    192. {
    193. cout << "String operator+(const String &, const char *)"<< endl;
    194. String tmp(lhs);
    195. tmp += pstr;
    196. return tmp;
    197. }
    198. String operator+(const char *pstr, const String &rhs)
    199. {
    200. cout << "String operator+(const char*, const String &)" << endl;
    201. String tmp(pstr);
    202. tmp += rhs;
    203. return tmp;
    204. }
    205. void test()
    206. {
    207. String s1;
    208. /* std::cin >> s1; */
    209. cout << "s1 = " << s1 << endl;
    210. cout << endl << endl;
    211. String s2 = "hello";
    212. cout << "s2 = " << s2 << endl;
    213. cout << endl << "1111" << endl;
    214. s2 = "world"; //error
    215. cout << "s2 = " << s2 << endl;
    216. cout << endl << endl;
    217. s2 = s2;
    218. cout << "s2 = " << s2 << endl;
    219. cout << endl << endl;
    220. String s3 = "wuhan";
    221. s3 += " welcome to string word";
    222. cout << "s3 = " << s3 << endl;
    223. }
    224. int main(int argc, char **argv)
    225. {
    226. test();
    227. return 0;
    228. }

  • 相关阅读:
    .net----数据库的访问ADO.NET、DataAdapter和DataSet
    论文解读(GRACE)《Deep Graph Contrastive Representation Learning》
    面试准备-操作系统
    【Python基础】Python文件操作介绍
    英伟达发布526.98 WHQL 显卡驱动,支持RTX 4080,三款即将上线游戏
    【Fabric】libfabric
    .NET周刊【6月第5期 2024-06-30】
    ML.NET在C#项目中的使用
    基于Python+Nodejs+MONGODB的电影推荐网站
    R语言使用lightgbm包构建多分类的LightGBM模型、使用predict函数和训练好的模型进行预测推理、将推理后的概率值转化为预测标签
  • 原文地址:https://blog.csdn.net/INGNIGHT/article/details/133501336