• 【C++】string类 _模拟实现 _源码[复习专用]


    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. namespace zwx
    7. {
    8. class string
    9. {
    10. public:
    11. //string迭代器就是指针
    12. typedef char* iterator;
    13. iterator begin()
    14. {
    15. return _str;
    16. }
    17. iterator end()
    18. {
    19. return _str + _size;
    20. }
    21. typedef const char* const_iterator;//*在const之后,表示char*指向的内容不可修改
    22. const_iterator begin() const //只能读,不能写
    23. {
    24. return _str;
    25. }
    26. const_iterator end() const
    27. {
    28. return _str + _size;
    29. }
    30. //构造函数
    31. string(const char* str = "")
    32. {
    33. _size = strlen(str);
    34. _capacity = _size;
    35. _str = new char[_capacity + 1];
    36. strcpy(_str, str);
    37. }
    38. // //传统写法 拷贝构造
    39. //string(const string& s)
    40. // :_str(new char[s._capacity+1])
    41. // , _size(s._size)
    42. // , _capacity(s._capacity)
    43. //{
    44. // strcpy(_str, s._str);
    45. //}
    46. operator=
    47. //string& operator=(const string& s)
    48. //{
    49. // if (this != &s)
    50. // {
    51. // char* tmp = new char[s._capacity + 1];
    52. // strcpy(tmp, s._str);
    53. // delete[] _str;
    54. // _str = tmp;
    55. // _size = s._size;
    56. // _capacity = s._capacity;
    57. // }
    58. // return *this;
    59. //}
    60. //现代写法
    61. void swap(string& tmp)
    62. {
    63. ::swap(_str, tmp._str);//::调用全局std中的swap
    64. ::swap(_size, tmp._size);
    65. ::swap(_capacity, tmp._capacity);
    66. }//全局中的swap函数会调用拷贝构造(自定义类型),string中的swap只进行成员变量的交换
    67. string(const string& s)
    68. :_str(nullptr)//可以delete nullptr,但是不能delete野指针
    69. , _size(0)
    70. , _capacity(0)
    71. {
    72. string tmp(s._str);//调用构造函数
    73. swap(tmp); //this->swap(tmp);
    74. }
    75. string& operator=(string s)//s顶替tmp做打工人
    76. {
    77. swap(s);
    78. return *this;
    79. }
    80. ~string()
    81. {
    82. delete[] _str;//可以delete nullptr,不能delete一个随机的空间
    83. _str = nullptr;
    84. _size = _capacity = 0;
    85. }
    86. const char* c_str() const
    87. {
    88. return _str;
    89. }
    90. size_t size() const//返回的是一个内置类型的数字
    91. {
    92. return _size;
    93. }
    94. size_t capacity() const
    95. {
    96. return _capacity;
    97. }
    98. const char& operator[](size_t pos) const
    99. {
    100. assert(pos < _size);
    101. return _str[pos];
    102. }
    103. char& operator[](size_t pos)//可以修改
    104. {
    105. assert(pos < _size);
    106. return _str[pos];
    107. }
    108. void reserve(size_t n)
    109. {
    110. if (n > _capacity)
    111. {
    112. char* tmp = new char[n + 1];
    113. strcpy(tmp, _str);
    114. delete[] _str;
    115. _str = tmp;
    116. _capacity = n;
    117. }
    118. }
    119. void resize(size_t n, char ch = '\0')
    120. {
    121. if (n > _size)
    122. {
    123. // 插入数据
    124. reserve(n);
    125. for (size_t i = _size; i < n; ++i)
    126. {
    127. _str[i] = ch;
    128. }
    129. _str[n] = '\0';
    130. _size = n;
    131. }
    132. else
    133. {
    134. // 删除数据
    135. _str[n] = '\0';
    136. _size = n;
    137. }
    138. }
    139. void push_back(char ch)
    140. {
    141. //满了就扩容
    142. if (_size == _capacity)
    143. {
    144. reserve(_capacity == 0 ? 4 : _capacity * 2);
    145. }
    146. _str[_size] = ch;
    147. ++_size;
    148. _str[_size] = '\0';
    149. }
    150. void append(const char* str)
    151. {
    152. size_t len = strlen(str);
    153. // 满了就扩容
    154. if (_size + len > _capacity)
    155. {
    156. reserve(_size+len);//容量刚好够用
    157. }
    158. strcpy(_str + _size, str);
    159. //strcat(_str, str); 需要找\0,效率低
    160. _size += len;
    161. }
    162. string& operator+=(char ch)
    163. {
    164. push_back(ch);
    165. return *this;
    166. }
    167. string& operator+=(const char* str)
    168. {
    169. append(str);
    170. return *this;
    171. }
    172. string& insert(size_t pos, char ch)
    173. {
    174. assert(pos <= _size);//pos前面插入
    175. if (_size == _capacity)
    176. {
    177. reserve(_capacity == 0 ? 4 : _capacity * 2);
    178. }
    179. size_t end = _size + 1;
    180. while (end > pos)
    181. {
    182. _str[end] = _str[end - 1];
    183. --end;
    184. }
    185. _str[pos] = ch;
    186. ++_size;
    187. return *this;
    188. }
    189. string& insert(size_t pos, const char* str)
    190. {
    191. assert(pos <= _size);
    192. size_t len = strlen(str);
    193. if (_size + len > _capacity)
    194. {
    195. reserve(_size + len);
    196. }
    197. size_t end = _size + len;
    198. while (end >= pos + len)
    199. {
    200. _str[end] = _str[end - len];
    201. --end;
    202. }
    203. strncpy(_str + pos, str, len);
    204. _size += len;
    205. return *this;
    206. }
    207. void erase(size_t pos, size_t len = npos)
    208. {
    209. assert(pos < _size);
    210. if (len == npos || pos + len >= _size)
    211. {
    212. _str[pos] = '\0';
    213. _size = pos;
    214. }
    215. else
    216. {
    217. strcpy(_str + pos, _str + pos + len);
    218. _size -= len;
    219. }
    220. }
    221. void clear()
    222. {
    223. _str[0] = '\0';
    224. _size = 0;//capacity不需要改变
    225. }
    226. size_t find(char ch, size_t pos = 0) const
    227. {
    228. assert(pos < _size);
    229. for (size_t i = pos; i < _size; ++i)
    230. {
    231. if (ch == _str[i])
    232. {
    233. return i;
    234. }
    235. }
    236. return npos;
    237. }
    238. size_t find(const char* sub, size_t pos = 0) const
    239. {
    240. assert(sub);
    241. assert(pos < _size);
    242. const char* ptr = strstr(_str + pos, sub);
    243. if (ptr == nullptr)
    244. {
    245. return npos;
    246. }
    247. else
    248. {
    249. return ptr - _str;
    250. }
    251. }
    252. string substr(size_t pos, size_t len = npos) const
    253. {
    254. assert(pos < _size);
    255. size_t realLen = len;
    256. if (len == npos || pos + len > _size)
    257. {
    258. realLen = _size - pos;
    259. }
    260. string sub;
    261. for (size_t i = 0; i < realLen; ++i)
    262. {
    263. sub += _str[pos + i];
    264. }
    265. return sub;
    266. }
    267. bool operator>(const string& s) const
    268. {
    269. return strcmp(_str, s._str) > 0;
    270. }
    271. bool operator==(const string& s) const
    272. {
    273. return strcmp(_str, s._str) == 0;
    274. }
    275. bool operator>=(const string& s) const
    276. {
    277. return *this > s || *this == s;
    278. }
    279. bool operator<=(const string& s) const
    280. {
    281. return !(*this > s);
    282. }
    283. bool operator<(const string& s) const
    284. {
    285. return !(*this >= s);
    286. }
    287. bool operator!=(const string& s) const
    288. {
    289. return !(*this == s);
    290. }
    291. private:
    292. char* _str;//指向字符串所在的空间
    293. size_t _size; //声明顺序为定义和初始化顺序
    294. size_t _capacity;//存储有效字符串的个数(不包括字符 '\0')
    295. public:
    296. // const static 语法特殊处理 --直接可以当成定义初始化
    297. const static size_t npos = -1;
    298. };
    299. //没有访问类中的私有,不需要实现友元
    300. //返回ostream& 实现连续插入
    301. ostream& operator<<(ostream& out, const string& s)
    302. {
    303. for (size_t i = 0; i < s.size(); ++i)
    304. {
    305. out << s[i];
    306. }
    307. return out;
    308. }
    309. istream& operator>>(istream& in, string& s)
    310. {
    311. s.clear();//与std库中的string一致
    312. char ch;
    313. ch = in.get();// 从输入流中提取字符
    314. const size_t N = 32;
    315. char buff[N];
    316. size_t i = 0;
    317. while (ch != ' ' && ch != '\n')
    318. {
    319. buff[i++] = ch;//避免每次都+=到s中 防止频繁的扩容
    320. if (i == N - 1)
    321. {
    322. buff[i] = '\0';
    323. s += buff;
    324. i = 0;
    325. }
    326. ch = in.get();
    327. }
    328. buff[i] = '\0';
    329. s += buff;
    330. return in;
    331. }
    332. }

  • 相关阅读:
    tsc : 无法加载文件 C:\Users\Administrat\AppData\Roaming\npm\tsc.ps 1,因为在此系统上禁止运行脚本
    如何运用 Kyligence 综合对比餐饮门店的销售能力?
    js看代码说输出
    C/C++ vector模拟实现
    pycharm安装jupyter,用德古拉主题,但是输入行全白了,看不清,怎么办?
    (阿里云)Linux部署SSM项目全过程
    电压继电器HDY-A/1-220VAC-1
    【工作技术栈】【源码解读】一次好奇心:单例模式下的ThreadLocal为什么要使用volatile和synchronized?
    Index Files and B+ Tree Refinements(听课笔记)
    python 的configparse 读取ini 文件
  • 原文地址:https://blog.csdn.net/qq_63179783/article/details/127645133