本文实现了c++ STL中的basic_string模板类,当然。通过typedef也就实现了string类和wstring类。限于篇幅,实现代码中用到了标准库的char_traits模板类,本人自己也实现了

char_traits模板类,为此还写了一篇博客,在我的博客里能够找到,那里的代码全然能够用在这里的basic_string类的实现中,当然,详细加到代码中要稍加修改,以和与basic_string类相关的全局模板函数兼容,如operator >> 模板函数的重载。

经过測试。这里的是实如今效率上不输标准库(与vs2012比对),代码凝视还算清晰,并且具有良好的扩充性。能够以此量身打造自己的精简版本号string。

好了。废话不多说了!看代码!

!!

还请高手们指教!!!

此文件我建议命名为local_string.h。还是我一惯的习惯,封装于名字空间mystd中。

假设要測试代码,直接复制以下的代码就能够了,都在一个文件里。

标准库有的功能。这里基本上都有!

  1. /*
  2. *看完《STL源代码剖析》后就有重写STL的冲动,这个basic_string的实现还算完整。
  3. 标准库有的功能,这里基本都有,假设有须要,能够在此基础上扩展功能。!
  4.  
  5.  
  6. 大家如有发现bug,请与我联系,以使代码不断地完好!!。
  7. *大家交流交流,谢谢!
  8. * 邮箱:sunkang2101024@foxmail.com
  9. */
  10.  
  11. // 建议此文件命名为 "local_string.h"
  12.  
  13. // vs2012 调试通过
  14. #pragma once
  15. #ifndef MYSTD_STRING_H_EX
  16. #define MYSTD_STRING_H_EX
  17. #include<cassert> // assert
  18. #include<cstddef> // std::size_t,std::ptrdiff_t
  19. #include<memory> // std::allocator
  20. #include<cstdlib> // rand()
  21. #include<exception> // std::out_of_range
  22. #include<iostream> //basic_istream, basic_ostream
  23.  
  24. #define MYSTD_BEGIN namespace mystd {
  25. #define MYSTD_END }
  26.  
  27. // mystd
  28. #ifdef __cplusplus
  29. MYSTD_BEGIN
  30. /////////////
  31. //随机訪问迭代器
  32. template<class random_access_iterator, class Value_type, class Reference,class Difference_type>
  33. class reverse_random_access_iterator{
  34. public:
  35. typedef Value_type value_type;
  36. typedef value_type* pointer;
  37. typedef Reference reference;
  38. typedef Difference_type difference_type;
  39. typedef std::size_t size_type;
  40. typedef std::random_access_iterator_tag reverse_iterator_category;
  41. public:
  42. random_access_iterator iterator;
  43. typedef reverse_random_access_iterator self;
  44. public:
  45. reverse_random_access_iterator()
  46. {
  47. //default constructor
  48. }
  49. explicit reverse_random_access_iterator(const random_access_iterator& tmp):iterator(tmp)
  50. {
  51. //constructor
  52. }
  53. reverse_random_access_iterator(const self& tmp):iterator(tmp.iterator)
  54. {
  55. // copy constructor
  56. }
  57. template<class random_access_iterator, class Value_type, class Reference,class Difference_type>
  58. reverse_random_access_iterator(const reverse_random_access_iterator<random_access_iterator,Value_type,Reference,Difference_type>& obj)
  59. :iterator(obj.iterator)
  60. {
  61. // 此构造函数主要为了进行转换之用,
  62. //reverse_iterator转换为 const_reverse_iterator
  63. }
  64. self& operator = (const self& tmp) // 能够不定义。直接使用默认的函数
  65. {
  66. iterator = tmp.iterator;
  67. return *this;
  68. }
  69. ~reverse_random_access_iterator()
  70. {
  71. // do nothing
  72. }
  73.  
  74. self& operator ++ ()
  75. {
  76. --iterator;
  77. return *this;
  78. }
  79. self operator ++ (int)
  80. {
  81. self tmp(*this);
  82. ++*this;
  83. return tmp;
  84. }
  85. self& operator -- ()
  86. {
  87. ++iterator;
  88. return *this;
  89. }
  90. self operator -- (int)
  91. {
  92. self tmp(*this);
  93. --*this;
  94. return tmp;
  95. }
  96.  
  97. self operator + (difference_type n) const
  98. {
  99. return self(iterator - n);
  100. }
  101. self operator - (difference_type n) const
  102. {
  103. return *this + (-n);
  104. }
  105. self& operator += (difference_type n)
  106. {
  107. iterator -= n;
  108. return *this;
  109. }
  110. self& operator -= (difference_type n)
  111. {
  112. iterator += n;
  113. return *this;
  114. }
  115. reference operator * () const
  116. {
  117. return *(iterator - 1);
  118. }
  119. bool operator == (const self& tmp) const
  120. {
  121. return iterator == tmp.iterator;
  122. }
  123. bool operator != (const self& tmp) const
  124. {
  125. return !(*this == tmp);
  126. }
  127. bool operator < (const self& tmp) const
  128. {
  129. return tmp.iterator < iterator;
  130. }
  131. bool operator <= (const self& tmp) const
  132. {
  133. return tmp.iterator <= iterator;
  134. }
  135. bool operator > (const self& tmp) const
  136. {
  137. return iterator < tmp.iterator;
  138. }
  139. bool operator >= (const self& tmp) const
  140. {
  141. return iterator <= tmp.iterator;
  142. }
  143. random_access_iterator base() const
  144. {
  145. return iterator;
  146. }
  147. friend difference_type operator - (const self& tmp_1,const self& tmp_2)
  148. {
  149. return tmp_2.iterator - tmp_1.iterator;
  150. }
  151. };
  152.  
  153. template<class T, class Reference,class Difference_type>
  154. class random_access_iterator{ // 反向随机訪问迭代器
  155. public:
  156. typedef T value_type;
  157. typedef value_type *pointer;
  158. typedef Reference reference;
  159. typedef Difference_type difference_type;
  160. typedef std::size_t size_type;
  161. typedef std::random_access_iterator_tag iterator_category;
  162. public:
  163. pointer ptr;
  164. typedef random_access_iterator self;
  165. public:
  166. random_access_iterator()
  167. {
  168. }
  169. explicit random_access_iterator(pointer tmp):ptr(tmp)
  170. {
  171. }
  172. random_access_iterator(const self& tmp):ptr(tmp.ptr)
  173. {
  174. }
  175. template<class T, class Reference,class Difference_type>
  176. random_access_iterator(const random_access_iterator<T,Reference,Difference_type>& obj)
  177. :ptr(obj.ptr)
  178. {
  179. // 此构造函数主要为了进行转换之用,
  180. //iterator转换为 const_iterator
  181. }
  182. self& operator = (const self& tmp)
  183. {
  184. ptr = tmp.ptr;
  185. return *this;
  186. }
  187. ~random_access_iterator()
  188. {
  189. }
  190.  
  191. self& operator ++ ()
  192. {
  193. ++ptr;
  194. return *this;
  195. }
  196. self operator ++ (int)
  197. {
  198. self tmp(*this);
  199. ++*this;
  200. return tmp;
  201. }
  202. self& operator -- ()
  203. {
  204. --ptr;
  205. return *this;
  206. }
  207. self operator -- (int)
  208. {
  209. self tmp(*this);
  210. --*this;
  211. return tmp;
  212. }
  213. reference operator * () const // 足够的自由度
  214. {
  215. return *ptr;
  216. }
  217. bool operator == (const self& tmp) const
  218. {
  219. return ptr == tmp.ptr;
  220. }
  221. bool operator != (const self& tmp) const
  222. {
  223. return !(*this == tmp);
  224. }
  225.  
  226. bool operator < (const self& tmp) const
  227. {
  228. return ptr < tmp.ptr;
  229. }
  230. bool operator <= (const self& tmp) const
  231. {
  232. return ptr <= tmp.ptr;
  233. }
  234. bool operator > (const self& tmp) const
  235. {
  236. return tmp.ptr < ptr;
  237. }
  238. bool operator >= (const self& tmp) const
  239. {
  240. return tmp.ptr <= ptr;
  241. }
  242. self operator + (difference_type n) const
  243. {
  244. return self(ptr + n);
  245. }
  246. self operator - (difference_type n) const
  247. {
  248. return *this + (-n);
  249. }
  250. self& operator += (difference_type n)
  251. {
  252. ptr += n;
  253. return *this;
  254. }
  255. self& operator -= (difference_type n)
  256. {
  257. ptr -= n;
  258. return *this;
  259. }
  260. friend difference_type operator - (const self& tmp_1,const self& tmp_2)
  261. {
  262. return tmp_1.ptr - tmp_2.ptr;
  263. }
  264. };
  265.  
  266. ////////////////////////
  267. //限于篇幅,这里的char_traits模板类用的是标准库的,
  268. //我的博客里有一篇文章是关于char_traits模板类的实现的,全然能够用在这里。
  269.  
  270. //
  271. template<class charT,class traits_type = std::char_traits<charT>,class Alloc = std::allocator<charT> >
  272. class basic_string
  273. {
  274. public:
  275. typedef mystd::random_access_iterator<charT,charT&,std::ptrdiff_t> iterator;
  276. typedef mystd::random_access_iterator<const charT,const charT&,std::ptrdiff_t> const_iterator;
  277. typedef mystd::reverse_random_access_iterator<iterator,charT,charT&,std::ptrdiff_t> reverse_iterator;
  278. typedef mystd::reverse_random_access_iterator<const_iterator,const charT,const charT&,std::ptrdiff_t> const_reverse_iterator;
  279. typedef typename iterator::value_type value_type;
  280. typedef typename iterator::reference reference;
  281. typedef typename iterator::pointer pointer;
  282. typedef typename iterator::size_type size_type;
  283. typedef typename iterator::difference_type difference_type;
  284. typedef typename iterator::iterator_category iterator_category;
  285. typedef typename const_iterator::reference const_reference;
  286. typedef typename const_iterator::pointer const_pointer;
  287. typedef Alloc allocator_type;
  288. public:
  289. static const size_type npos = size_type(-1);
  290. private:
  291. pointer start,finish,end_of_storage; //数据成员
  292. typedef basic_string self; //私有类型
  293. allocator_type alloc; // 分配器
  294. private: // 内部使用函数
  295. size_type alloc_capacity(size_type old_size) const // 容量分配函数
  296. { //这个函数主要是为了方便改动分配方案,
  297. //能够依照须要改动。可是要确保返回值大于old_size,以此保证capacity()非空(看实现可知)
  298. // 提示:与c_str()的实现有关。
  299. if(old_size < 10)
  300. return 10; //wstring
  301. else if(old_size < 100)
  302. return old_size * 2;
  303. else if(old_size < 1024)
  304. return old_size + old_size / 10;
  305. else
  306. return old_size + rand() % 1024 + 1;
  307. //返回值得大于old_size
  308. }
  309. void fill_n(pointer first,size_type n,value_type val)
  310. {
  311. assert(first != 0);
  312. while(n--)
  313. *first++ = val;
  314. }
  315. void fill(pointer first,pointer last,value_type val)
  316. {
  317. assert(first != 0 && last != 0);
  318. while(first != last)
  319. *first++ = val;
  320. }
  321.  
  322. iterator insert_aux(size_type pos,const self& str)
  323. { //用于insert相关函数
  324. assert(pos <= size());
  325. if(str.empty())
  326. return iterator(start+pos);
  327. if(size()+str.size() > capacity()) // 无论this是否等于&str
  328. {
  329. size_type str_size = str.size(); //
  330. size_type old_size = size();
  331. size_type capacity_size = alloc_capacity(size()+str_size);
  332. pointer new_start = alloc.allocate(capacity_size);
  333. traits_type::copy(new_start,start,pos);
  334. traits_type::copy(new_start+pos,str.start,str_size);
  335. traits_type::copy(new_start+pos+str_size,start+pos,old_size-pos);
  336. alloc.deallocate(start,capacity());
  337. start = new_start;
  338. finish = start + old_size+ + str_size; //
  339. end_of_storage = start + capacity_size;
  340. return iterator(start+pos);
  341. }
  342. else if(this != &str)
  343. {
  344. traits_type::move(start+pos+str.size(),start+pos,size()-pos);
  345. traits_type::copy(start+pos,str.start,str.size());
  346. finish += str.size();
  347. return iterator(start+pos);
  348. }
  349. else
  350. {
  351. size_type len_left = pos;
  352. size_type len_right = size() - pos;
  353. traits_type::copy(start+len_left*2+len_right,start+len_left,len_right);
  354. traits_type::copy(start+len_left,start,len_left);
  355. traits_type::copy(start+len_left*2,start+len_left*2+len_right,len_right);
  356. finish += str.size();
  357. return iterator(start+len_left);
  358. }
  359. }
  360. iterator erase_aux(size_type first,size_type last)
  361. { //用于erase函数
  362. assert(first <= last && last <= size());
  363. if(first > size())
  364. throw std::out_of_range("invalid string position");
  365. if(first == last)
  366. return iterator(start+first);
  367. traits_type::copy(start+first,start+last,size()-last);
  368. finish -= last - first;
  369. return iterator(start+first);
  370. }
  371. void empty_init()
  372. { //用于初始化
  373. size_type capacity_size = alloc_capacity(1);
  374. start = alloc.allocate(capacity_size); //分配一定的空间
  375. finish = start;
  376. end_of_storage = start + capacity_size;
  377. }
  378. void swap(pointer& x,pointer& y)
  379. {
  380. assert(x != 0 && y != 0);
  381. pointer temp = x;
  382. x = y;
  383. y = temp;
  384. }
  385. bool is_inside(const self& str,value_type val) const
  386. { // 后面的查找功能的函数会用到,如find_first_of()函数
  387. size_type n = str.size();
  388. for(size_type i = 0; i < n; ++i)
  389. if(traits_type::eq(str[i],val))
  390. return true;
  391. return false;
  392. }
  393. public:
  394. basic_string():start(0),finish(0),end_of_storage(0)
  395. {
  396. assert(sizeof(value_type) <= sizeof(wchar_t));
  397. empty_init();
  398. }
  399. basic_string(size_type n,value_type val):start(0),finish(0),end_of_storage(0)
  400. {
  401. assert(sizeof(value_type) <= sizeof(wchar_t));
  402. size_type capacity_size = alloc_capacity(n);
  403. start = alloc.allocate(capacity_size);
  404. finish = start + n;
  405. end_of_storage = start + capacity_size;
  406. fill_n(start,n,val);
  407. }
  408. basic_string(const self& str,size_type pos,size_type len = npos)
  409. {
  410. assert(sizeof(value_type) <= sizeof(wchar_t));
  411. assert(pos <= str.size());
  412. if(str.empty())
  413. empty_init();
  414. else
  415. {
  416. if(len == npos || len > str.size()-pos)
  417. len = str.size() - pos;
  418. size_type capacity_size = alloc_capacity(len);
  419. start = alloc.allocate(capacity_size);
  420. traits_type::copy(start,str.start+pos,len);
  421. finish = start + len;
  422. end_of_storage = start + capacity_size;
  423. }
  424. }
  425. //这个构造函数不可用explicitkeyword。后面大量用到此构造函数做隐式转换
  426. basic_string(const_pointer str):start(0),finish(0),end_of_storage(0)
  427. {
  428. assert(sizeof(value_type) <= sizeof(wchar_t) && str != 0);
  429. size_type str_size = traits_type::length(str);
  430. size_type capacity_size = alloc_capacity(str_size);
  431. start = alloc.allocate(capacity_size);
  432. traits_type::copy(start,str,str_size);
  433. finish = start + str_size;
  434. end_of_storage = start + capacity_size;
  435. }
  436. basic_string(const_pointer str,size_type n):start(0),finish(0),end_of_storage(0)
  437. {
  438. assert(sizeof(value_type) <= sizeof(wchar_t) && str != 0);
  439. size_type len = traits_type::length(str);
  440. //标准库没有对长度进行调整(測试vs2012的执行结果可知),本人认为应该加上。这样有更好的容错性
  441. //当然。在str非常大的时候,效率上会有点折扣(计算长度的时间花销上)
  442. if(n > len)
  443. n = len;
  444. size_type capacity_size = alloc_capacity(n);
  445. start = alloc.allocate(capacity_size);
  446. traits_type::copy(start,str,n);
  447. finish = start + n;
  448. end_of_storage = start + capacity_size;
  449. }
  450. template <class InputIterator>
  451. basic_string(InputIterator first,InputIterator last):start(0),finish(0),end_of_storage(0)
  452. {
  453. assert(sizeof(value_type) <= sizeof(wchar_t));
  454. size_type len = 0;
  455. InputIterator new_first = first;
  456. while(new_first != last) //用后自增測试时会出现一点问题
  457. ++len, ++new_first;
  458. size_type capacity_size = alloc_capacity(len);
  459. start = alloc.allocate(capacity_size);
  460. finish = start + len;
  461. /*while(first != last)
  462. *start++ = *first++;*/
  463. while(last != first) //用后自增測试时会出现一点问题
  464. *--finish = *--last;
  465. finish = start + len; // 复位
  466. end_of_storage = start + capacity_size;
  467. }
  468. basic_string(const self& tmp):start(0),finish(0),end_of_storage(0)
  469. {
  470. assert(sizeof(value_type) <= sizeof(wchar_t));
  471. start = alloc.allocate(tmp.capacity());
  472. finish = start + tmp.size();
  473. end_of_storage = start + tmp.capacity();
  474. traits_type::copy(start,tmp.start,tmp.size());
  475. }
  476.  
  477. self& operator = (const self& tmp)
  478. {
  479. if(this == &tmp) // 防止自身复制
  480. return *this;
  481. clear();
  482. if(tmp.empty())
  483. return *this;
  484. if(capacity() >= tmp.capacity())
  485. {
  486. traits_type::copy(start,tmp.start,tmp.size());
  487. finish = start + tmp.size();
  488. }
  489. else
  490. {
  491. size_type capacity_size = alloc_capacity(tmp.size());
  492. alloc.deallocate(start,capacity()); // 释放原有空间
  493. start = alloc.allocate(capacity_size);
  494. traits_type::copy(start,tmp.start,tmp.size());
  495. finish = start + tmp.size();
  496. end_of_storage = start + capacity_size;
  497. }
  498. return *this;
  499. }
  500. self& operator = (value_type val)
  501. {
  502. clear(); // 不释放内存,看代码可知
  503. insert_aux(0,self(1,val));
  504. return *this;
  505. }
  506. ~basic_string()
  507. {
  508. //alloc.deallocate(start,capacity());
  509. //由于capacity()实现上的缘故,这里用end_of_storage - start(看capacity代码可知)
  510. //当然,第二个參数其实没实用。随意写一个数字都可
  511. alloc.deallocate(start,end_of_storage - start);
  512. }
  513. public:
  514. size_type size() const throw()
  515. { //依照标准文档的要求,不抛出异常,下面同理可得,不再赘述!
  516. return finish - start;
  517. }
  518. size_type length() const throw()
  519. {
  520. return size();
  521. }
  522. size_type max_size() const throw()
  523. {
  524. return size_type(-1) / sizeof(value_type) - 1;
  525. }
  526. size_type capacity() const throw()
  527. { //这里的计算本来不应该减 1 的,有意这样做是为了确保留有一个字符的空间(包括宽字符),方便做
  528. // C风格字符串的转换,写入空字符,用于成员函数c_str()
  529. return end_of_storage - start - 1;
  530. }
  531. bool empty() const throw()
  532. {
  533. return start == finish;
  534. }
  535. iterator begin() throw()
  536. {
  537. return iterator(start);
  538. }
  539. const_iterator begin() const throw()
  540. {
  541. return const_iterator(start);
  542. }
  543. iterator end() throw()
  544. {
  545. return iterator(finish);
  546. }
  547. const_iterator end() const throw()
  548. {
  549. return const_iterator(finish);
  550. }
  551. reverse_iterator rbegin() throw()
  552. {
  553. return reverse_iterator(end());
  554. }
  555. const_reverse_iterator rbegin() const throw()
  556. {
  557. return const_reverse_iterator(end());
  558. }
  559. reverse_iterator rend() throw()
  560. {
  561. return reverse_iterator(begin());
  562. }
  563. const_reverse_iterator rend() const throw()
  564. {
  565. return const_reverse_iterator(begin());
  566. }
  567. reference operator [] (size_type n) throw()
  568. {
  569. assert(n < size());
  570. return *(start + n);
  571. }
  572. const_reference operator [] (size_type n) const throw()
  573. {
  574. assert(n < size());
  575. return *(start + n);
  576. }
  577. reference at(size_type n)
  578. {
  579. if(n < size())
  580. return *(start + n);
  581. else
  582. throw std::out_of_range("invalid string position");
  583. }
  584. const_reference at(size_type n) const
  585. {
  586. if(n < size())
  587. return *(start + n);
  588. else
  589. throw std::out_of_range("invalid string position");
  590. }
  591. allocator_type get_allocator() const throw()
  592. {
  593. return allocator_type();
  594. }
  595. void reserve(size_type n = 0)
  596. {
  597. if(n <= capacity())
  598. ;
  599. else
  600. {
  601. size_type capacity_size = alloc_capacity(n);
  602. size_type old_size = size();
  603. pointer new_start = alloc.allocate(capacity_size);
  604. traits_type::copy(new_start,start,size());
  605. alloc.deallocate(start,capacity());
  606. start = new_start;
  607. finish = start + old_size;
  608. end_of_storage = start + capacity_size;
  609. }
  610. }
  611. void clear()
  612. {
  613. finish = start; //并不释放内存
  614. }
  615. self substr(size_type pos = 0,size_type len = npos) const
  616. {
  617. assert(pos <= size());
  618. return self(*this,pos,len); // 显式调用构造函数
  619. }
  620. self& insert(size_type pos,const self& str)
  621. {
  622. assert(pos <= size());
  623. insert_aux(pos,str);
  624. return *this;
  625. }
  626. const_pointer c_str() const throw()
  627. { //构造函数保证capacity() != 0,或者说start,finish,end_of_storage不为空指针
  628. //当然,这和详细的实现有关,这是我的一个实现
  629. *finish = 0; // 转换成C风格的字符串
  630. return start;
  631. }
  632. const_pointer data() const throw()
  633. {
  634. *finish = 0;
  635. // 也能够直接返回start,标准文档没有强制要求为C风格字符串
  636. return start;
  637. }
  638. self& insert(size_type pos,const self& str,size_type subpos,size_type sublen)
  639. {
  640. assert(pos <= size());
  641. insert_aux(pos,str.substr(subpos,sublen));
  642. return *this;
  643. }
  644. self& insert(size_type pos,const_pointer str)
  645. {
  646. assert(pos <= size() && str != 0);
  647. insert_aux(pos,self(str));
  648. return *this;
  649. }
  650. self& insert(size_type pos,const_pointer str,size_type n)
  651. {
  652. assert(pos <= size() && str != 0);
  653. insert_aux(pos,self(str,n));
  654. return *this;
  655. }
  656.  
  657. self& insert(size_type pos,size_type n,value_type val)
  658. {
  659. assert(pos <= size());
  660. insert_aux(pos,self(n,val));
  661. return *this;
  662. }
  663. void insert(iterator itr,size_type n,value_type val)
  664. {
  665. assert(itr >= begin() && itr <= end());
  666. insert_aux(itr-begin(),self(n,val));
  667. }
  668. iterator insert(iterator itr,value_type val)
  669. {
  670. assert(itr >= begin() && itr <= end());
  671. return insert_aux(itr-begin(),self(1,val));
  672. }
  673. template <class InputIterator>
  674. void insert(iterator itr,InputIterator first,InputIterator last)
  675. {
  676. assert(itr >= begin() && itr <= end());
  677. insert_aux(itr-begin(),self(first,last));
  678. }
  679. self& erase(size_type pos = 0,size_type len = npos)
  680. {
  681. assert(pos <= size());
  682. if(pos > size())
  683. throw std::out_of_range("invalid string position");
  684. if(len == npos || len > size()-pos)
  685. len = size() - pos;
  686. erase_aux(pos,pos+len);
  687. return *this;
  688. }
  689.  
  690. iterator erase(iterator itr)
  691. {
  692. assert(itr >= begin() && itr < end());
  693. return erase_aux(itr-begin(),itr-begin()+1);
  694. }
  695. iterator erase(iterator first,iterator last)
  696. {
  697. assert(first >= begin() && first <= last && last <= end());
  698. return erase_aux(first-begin(),last-begin());
  699. }
  700. void push_back(value_type val)
  701. {
  702. insert_aux(size(),self(1,val));
  703. }
  704. self& append(const self& str)
  705. {
  706. return *this += str;
  707. }
  708.  
  709. self& append(const self& str,size_type subpos,size_type sublen)
  710. {
  711. return *this += str.substr(subpos,sublen);
  712. }
  713.  
  714. self& append(const_pointer str)
  715. {
  716. assert(str != 0);
  717. return *this += str;
  718. }
  719.  
  720. self& append(const_pointer str,size_type n)
  721. {
  722. assert(str != 0);
  723. return *this += self(str,n);
  724. }
  725.  
  726. self& append(size_type n,value_type val)
  727. {
  728. return *this += self(n,val);
  729. }
  730.  
  731. template <class InputIterator>
  732. self& append(InputIterator first,InputIterator last)
  733. {
  734. return *this += self(first,last);
  735. }
  736. self& assign(const self& str)
  737. {
  738. return *this = str;
  739. }
  740.  
  741. self& assign(const self& str,size_type subpos,size_type sublen)
  742. {
  743. return *this = self(str,subpos,sublen);
  744. }
  745.  
  746. self& assign(const_pointer str)
  747. {
  748. assert(str != 0);
  749. return *this = self(str);
  750. }
  751.  
  752. self& assign(const_pointer str,size_type n)
  753. {
  754. assert(str != 0);
  755. return *this = self(str,n);
  756. }
  757. self& assign(size_type n,value_type val)
  758. {
  759. return *this = self(n,val);
  760. }
  761.  
  762. template <class InputIterator>
  763. self& assign(InputIterator first,InputIterator last)
  764. {
  765. return *this = self(first,last);
  766. }
  767. void resize(size_type n)
  768. {
  769. resize(n,0); //转调
  770. }
  771. void resize(size_type n,value_type val)
  772. {
  773. if(n <= size())
  774. finish -= size() - n;
  775. else if(n <= capacity())
  776. {
  777. fill(finish,finish+n,val);
  778. finish += n - size();
  779. }
  780. else
  781. {
  782. size_type capacity_size = alloc_capacity(n);
  783. pointer new_start = alloc.allocate(capacity_size);
  784. traits_type::copy(new_start,start,size());
  785. fill(new_start+size(),new_start+n,val);
  786. alloc.deallocate(start,capacity());
  787. start = new_start;
  788. finish = start + n;
  789. end_of_storage = start + capacity_size;
  790. }
  791. }
  792. void swap(self& str)
  793. {
  794. if(this == &str)
  795. return ;
  796. swap(start,str.start);
  797. swap(finish,str.finish);
  798. swap(end_of_storage,str.end_of_storage);
  799. }
  800.  
  801. self& replace(size_type pos,size_type len,const self& str)
  802. {
  803. assert(pos <= size());
  804. if(pos > size())
  805. throw std::out_of_range("invalid string position");
  806. // 后面的replace重载函数就不用写异常了,由于都会直接或间接地调用到这个函数
  807. if(len > size() - pos)
  808. len = size() - pos;
  809. if(size() + str.size() - len > capacity())
  810. {
  811. size_type new_size = size()+str.size()-len;
  812. size_type capacity_size = alloc_capacity(new_size);
  813. pointer new_start = alloc.allocate(capacity_size);
  814. traits_type::copy(new_start,start,pos);
  815. traits_type::copy(new_start+pos,str.start,str.size());
  816. traits_type::copy(new_start+pos+str.size(),start+pos+len,size()-pos-len);
  817. alloc.deallocate(start,capacity());
  818. start = new_start;
  819. finish = start + new_size;
  820. end_of_storage = start + capacity_size;
  821. }
  822. else if(this != &str) //假设不是自身的替换
  823. {
  824. if(str.size() <= len)
  825. {
  826. traits_type::copy(start+pos,str.start,str.size());
  827. erase(pos+str.size(),len-str.size()); // 长度len - str.size()
  828. // finish 已经更新
  829. }
  830. else // size() + str.size() - len <= capacity()
  831. {
  832. traits_type::move(start+pos+str.size(),start+pos+len,size()-pos-len);
  833. traits_type::copy(start+pos,str.start,str.size());
  834. finish += str.size() - len;
  835. }
  836. }
  837. else
  838. return replace(pos,len,self(str)); //递归调用,这次不会是自身了。
  839. return *this;
  840. }
  841.  
  842. self& replace(iterator itr_1,iterator itr_2,const self& str)
  843. {
  844. assert(itr_1 >= begin() && itr_2 <= end());
  845. return replace(itr_1-begin(),itr_2-itr_1,str); // 转调
  846. }
  847. self& replace(size_type pos,size_type len,const self& str,
  848. size_type subpos,size_type sublen)
  849. {
  850. assert(pos <= size());
  851. return replace(pos,len,str.substr(subpos,sublen));
  852. }
  853.  
  854. self& replace(size_type pos,size_type len,const_pointer str)
  855. {
  856. assert(pos <= size() && str != 0);
  857. return replace(pos,len,self(str));
  858. }
  859. self& replace(iterator itr_1,iterator itr_2,const_pointer str)
  860. {
  861. assert(itr_1 >= begin() && itr_2 <= end());
  862. return replace(itr_1,itr_2,self(str)); //转调
  863. }
  864. self& replace(size_type pos,size_type len,const_pointer str,size_type n)
  865. {
  866. assert(pos <= size() && str != 0);
  867. return replace(pos,len,self(str,n));
  868. }
  869. self& replace(iterator itr_1,iterator itr_2,const_pointer str,size_type n)
  870. {
  871. assert(itr_1 >= begin() && itr_2 <= end() && str != 0);
  872. return replace(itr_1,itr_2,self(str,n));
  873. }
  874.  
  875. self& replace(size_type pos,size_type len,size_type n,value_type val)
  876. {
  877. assert(pos <= size());
  878. return replace(pos,len,self(n,val));
  879. }
  880. self& replace(iterator itr_1,iterator itr_2,size_type n,value_type val)
  881. {
  882. assert(itr_1 >= begin() && itr_2 <= end());
  883. return replace(itr_1,itr_2,self(n,val));
  884. }
  885.  
  886. template <class InputIterator>
  887. self& replace(iterator itr_1,iterator itr_2,InputIterator first,InputIterator last)
  888. {
  889. assert(itr_1 >= begin() && itr_2 <= end());
  890. return replace(itr_1,itr_2,self(first,last));
  891. }
  892. int compare(const self& str) const
  893. { //后面的compare重载函数都间接调用此函数
  894. if(this == &str)
  895. return 0;
  896. size_type num = size() >= str.size() ? size() : str.size();
  897. return traits_type::compare(c_str(),str.c_str(),num); //须要转换为C风格字符串
  898. }
  899. int compare(size_type pos,size_type len,const self& str) const
  900. {
  901. assert(pos <= size());
  902. if(pos > size()) // 后面的重载函数不用写异常了。这里写了
  903. throw std::out_of_range("invalid string position");
  904. //size_type num = len >= str.size() ? len : str.size();
  905. //return traits_type::compare(start+pos,str.start,num);
  906. return substr(pos,len).compare(str); //转调
  907. }
  908. int compare(size_type pos,size_type len,const self& str,
  909. size_type subpos,size_type sublen) const
  910. {
  911. assert(pos <= size());
  912. return compare(pos,len,self(str,subpos,sublen)); //转调
  913. }
  914.  
  915. int compare(const_pointer str) const
  916. {
  917. assert(str != 0);
  918. return compare(self(str));
  919. }
  920. int compare(size_type pos,size_type len,const_pointer str) const
  921. {
  922. assert(pos <= size() && str != 0);
  923. return compare(pos,len,self(str));
  924. }
  925.  
  926. int compare(size_type pos,size_type len,const_pointer str,size_type n) const
  927. {
  928. assert(pos <= size() && str != 0);
  929. return compare(pos,len,self(str,n));
  930. }
  931. size_type copy(pointer str,size_type len,size_type pos = 0) const
  932. {
  933. assert(pos <= size() && str != 0);
  934. if(len + pos > size())
  935. len = size() - pos; // 调整一下长度
  936. traits_type::copy(str,start+pos,len);
  937. return len;
  938. }
  939. size_type find(const self& str,size_type pos = 0) const throw()
  940. { //pos为搜索開始处,用数学区间表示为[pos,size() )
  941. assert(pos <= size());
  942. if(empty())
  943. return npos;
  944. size_type len_str = str.size();
  945. size_type len = size() - pos;
  946. if(len < len_str)
  947. return npos;
  948. size_type end_pos = size() - len_str; // 调整了一下有效长度,避免做无用功
  949. while(pos <= end_pos)
  950. {
  951. if(compare(pos,len_str,str) == 0) // 转调重载的成员函数
  952. return pos;
  953. else
  954. ++pos;
  955. }
  956. return npos;
  957. }
  958.  
  959. size_type find(const_pointer str,size_type pos = 0) const throw()
  960. {
  961. assert(pos <= size() && str != 0);
  962. if(empty())
  963. return npos;
  964. return find(self(str),pos); // 转调重载的成员函数
  965. }
  966.  
  967. size_type find(const_pointer str,size_type pos,size_type n) const throw()
  968. { //str中的n个字符,注意 n 的详细所指
  969. assert(pos <= size() && str != 0);
  970. if(empty())
  971. return npos;
  972. return find(self(str,n),pos);// 转调重载的成员函数
  973. }
  974.  
  975. size_type find(value_type val,size_type pos = 0) const throw()
  976. {
  977. assert(pos <= size());
  978. if(empty())
  979. return npos;
  980. return find(self(1,val),pos); // 转调重载的成员函数
  981. }
  982.  
  983. size_type rfind(const self& str,size_type pos = npos) const throw()
  984. { // pos为搜索開始处,用数学区间表示为[0,pos]
  985. if(empty())
  986. return npos;
  987. if(pos == npos || pos >= size()) //加上pos == npos的推断并不是多此一举
  988. pos = size() - 1;
  989. if(size() < str.size())
  990. return npos;
  991. size_type len_str = str.size();
  992. if(pos > size() - len_str)
  993. pos = size() - len_str; // 调整位置,避免做没用的搜索
  994. while(pos >= 0 && pos != size_type(-1))
  995. {
  996. if(compare(pos,len_str,str) == 0) // 转调成员函数
  997. return pos;
  998. else
  999. --pos;
  1000. }
  1001. return npos;
  1002. }
  1003.  
  1004. size_type rfind(const_pointer str,size_type pos = npos) const throw()
  1005. {
  1006. assert(str != 0);
  1007. if(empty())
  1008. return npos;
  1009. if(pos == npos || pos >= size()) //加上pos == npos的推断并不是多此一举
  1010. pos = size() - 1;
  1011. return rfind(self(str),pos); // 转调重载的成员函数
  1012. }
  1013.  
  1014. size_type rfind(const_pointer str,size_type pos,size_type n) const throw()
  1015. { // n为str须要搜索字符的个数,由于构造函数实现上的差异,我的n值在调用构造函数时会有调整,
  1016. // 这样是为了增强容错性,可是測试vs2012可知此实现上没有此功能,
  1017. //因此。用标准库时,依赖于用户使用正确的n值,否则会得不到预期的结果。
  1018. // 用我的这个实现,当n值大于str的长度时。会匹配整个str字符串
  1019. //相似情况同理可知,不再赘述。
  1020. assert(str != 0);
  1021. if(empty())
  1022. return npos;
  1023. if(pos >= size())
  1024. pos = size() - 1;
  1025. return rfind(self(str,n),pos); // 转调重载的成员函数
  1026. }
  1027.  
  1028. size_type rfind(value_type val,size_type pos = npos) const throw()
  1029. {
  1030. if(empty())
  1031. return npos;
  1032. if(pos == npos || pos >= size())
  1033. pos = size() - 1;
  1034. return rfind(self(1,val),pos); // 转调重载的成员函数
  1035. }
  1036. size_type find_first_of(const self& str,size_type pos = 0) const throw()
  1037. { //pos为搜索開始处。用数学区间表示为[pos,size() )
  1038. assert(pos <= size());
  1039. if(empty())
  1040. return npos;
  1041. size_type end_pos = size();
  1042. while(pos != end_pos && !is_inside(str,*(start+pos)))
  1043. ++pos;
  1044. if(pos == end_pos)
  1045. return npos;
  1046. else
  1047. return pos;
  1048. }
  1049.  
  1050. size_type find_first_of(const_pointer str,size_type pos = 0) const throw()
  1051. { //pos为搜索開始处,范围为[pos,size() )
  1052. assert(pos <= size() && str != 0);
  1053. if(empty())
  1054. return npos;
  1055. return find_first_of(self(str),pos); // 转调重载的成员函数
  1056. }
  1057.  
  1058. size_type find_first_of(const_pointer str,size_type pos, size_type n) const throw()
  1059. { //pos为搜索開始处,范围为[pos,size() )
  1060. assert(pos <= size() && str != 0);
  1061. if(empty())
  1062. return npos;
  1063. return find_first_of(self(str,n),pos); // // 转调重载的成员函数
  1064. }
  1065.  
  1066. size_type find_first_of(value_type val,size_type pos = 0) const throw()
  1067. { //pos为搜索開始处,范围为[pos,size() )
  1068. assert(pos <= size());
  1069. if(empty())
  1070. return npos;
  1071. return find_first_of(self(1,val),pos); // 转调重载的成员函数
  1072. }
  1073. size_type find_last_of(const self& str,size_type pos = npos) const throw()
  1074. { //pos 搜索结束处。范围[0,pos],包括pos
  1075. if(empty())
  1076. return npos;
  1077. if(pos == npos || pos >= size()) //加上pos == npos的推断并不是多此一举
  1078. pos = size() - 1;
  1079. while(pos >= 0 && pos != size_type(-1) &&
  1080. !is_inside(str,*(start+pos)))
  1081. --pos;
  1082. if(pos != size_type(-1))
  1083. return pos;
  1084. else
  1085. return npos;
  1086. }
  1087.  
  1088. size_type find_last_of(const_pointer str,size_type pos = npos) const throw()
  1089. { //pos 搜索结束处。范围[0,pos],包括pos
  1090. if(empty())
  1091. return npos;
  1092. assert(str != 0);
  1093. if(pos == npos || pos >= size())
  1094. pos = size() - 1;
  1095. return find_last_of(self(str),pos); // 转调重载的成员函数
  1096. }
  1097.  
  1098. size_type find_last_of(const_pointer str,size_type pos,size_type n) const throw()
  1099. { //pos 搜索结束处,范围[0,pos],包括pos
  1100. assert(str != 0);
  1101. if(empty())
  1102. return npos;
  1103. if(pos >= size())
  1104. pos = size() - 1;
  1105. return find_last_of(self(str,n),pos); // 转调重载的成员函数
  1106. }
  1107.  
  1108. size_type find_last_of(value_type val,size_type pos = npos) const throw()
  1109. { //pos 搜索结束处,范围[0,pos],包括pos
  1110. if(empty())
  1111. return npos;
  1112. if(pos == npos || pos >= size())
  1113. pos = size() - 1;
  1114. return find_last_of(self(1,val),pos); // 转调重载的成员函数
  1115. }
  1116. size_type find_first_not_of(const self& str,size_type pos = 0) const throw()
  1117. { //pos 为搜索開始处,范围[pos,size() )
  1118. assert(pos <= size());
  1119. if(empty())
  1120. return npos;
  1121. size_type end_pos = size();
  1122. while(pos != end_pos && is_inside(str,*(start+pos)))
  1123. ++pos;
  1124. if(pos == end_pos)
  1125. return npos;
  1126. else
  1127. return pos;
  1128. }
  1129. size_type find_first_not_of(const_pointer str,size_type pos = 0) const throw()
  1130. { //pos 为搜索開始处,范围[pos,size() )
  1131. assert(pos <= size() && str != 0);
  1132. if(empty())
  1133. return npos;
  1134. return find_first_not_of(self(str),pos);
  1135. }
  1136.  
  1137. size_type find_first_not_of(const_pointer str,size_type pos,size_type n) const throw()
  1138. { //pos 为搜索開始处,范围[pos,size() )
  1139. assert(pos <= size() && str != 0);
  1140. if(empty())
  1141. return npos;
  1142. return find_first_not_of(self(str,n),pos); // 转调重载的成员函数
  1143. }
  1144.  
  1145. size_type find_first_not_of(value_type val,size_type pos = 0) const throw()
  1146. { //pos 为搜索開始处,范围[pos,size() )
  1147. assert(pos <= size());
  1148. if(empty())
  1149. return npos;
  1150. return find_first_not_of(self(1,val),pos);
  1151. }
  1152. size_type find_last_not_of(const self& str,size_type pos = npos) const throw()
  1153. { //pos 搜索结束处,范围[0,pos]
  1154. if(empty())
  1155. return npos;
  1156. if(pos == npos || pos >= size())
  1157. pos = size() - 1;
  1158. while(pos >= 0 && pos != size_type(-1) &&
  1159. is_inside(str,*(start+pos)))
  1160. --pos;
  1161. if(pos != size_type(-1))
  1162. return pos;
  1163. else
  1164. return npos;
  1165. }
  1166. size_type find_last_not_of (const_pointer str,size_type pos = npos) const throw()
  1167. { //pos 搜索结束处,范围[0,pos]
  1168. assert(str != 0);
  1169. if(empty())
  1170. return npos;
  1171. if(pos == npos || pos >= size()) //加上pos == npos的推断并不是多此一举
  1172. pos = size() - 1;
  1173. return find_last_not_of(self(str),pos); // 转调重载的成员函数
  1174. }
  1175.  
  1176. size_type find_last_not_of (const_pointer str,size_type pos,size_type n) const throw()
  1177. { //pos 搜索结束处,范围[0,pos]
  1178. assert(str != 0);
  1179. if(empty())
  1180. return npos;
  1181. if(pos >= size())
  1182. pos = size() - 1;
  1183. return find_last_not_of(self(str,n),pos); // 转调重载的成员函数
  1184. }
  1185.  
  1186. size_type find_last_not_of (value_type val,size_type pos = npos) const throw()
  1187. { //pos 搜索结束处,范围[0,pos]
  1188. if(empty())
  1189. return npos;
  1190. if(pos == npos || pos >= size())
  1191. pos = size() - 1;
  1192. return find_last_not_of(self(1,val),pos); // 转调重载的成员函数
  1193. }
  1194. self& operator += (const self& str)
  1195. {
  1196. insert_aux(size(),str);
  1197. return *this;
  1198. }
  1199. self& operator += (value_type val)
  1200. {
  1201. insert_aux(size(),self(1,val));
  1202. return *this;
  1203. }
  1204.  
  1205. friend self operator + (const self& str1,const self& str2)
  1206. {
  1207. return self(str1) += str2;
  1208. }
  1209. friend self operator + (const self& str,value_type val)
  1210. {
  1211. return self(str) += self(1,val);
  1212. }
  1213. friend self operator + (value_type val,const self& str)
  1214. {
  1215. return self(1,val) += str;
  1216. }
  1217. friend void swap(self& str1,self& str2)
  1218. {
  1219. if(&str1 == &str2)
  1220. return ;
  1221. str1.swap(str2);
  1222. }
  1223. friend bool operator == (const self& str1,const self& str2)
  1224. {
  1225. return str1.compare(str2) == 0;
  1226. }
  1227. friend bool operator != (const self& str1,const self& str2)
  1228. {
  1229. return str1.compare(str2) != 0;
  1230. }
  1231. friend bool operator < (const self& str1,const self& str2)
  1232. {
  1233. return str1.compare(str2) < 0;
  1234. }
  1235. friend bool operator <= (const self& str1,const self& str2)
  1236. {
  1237. return str1.compare(str2) <= 0;
  1238. }
  1239. friend bool operator > (const self& str1,const self& str2)
  1240. {
  1241. return str1.compare(str2) > 0;
  1242. }
  1243. friend bool operator >= (const self& str1,const self& str2)
  1244. {
  1245. return str1.compare(str2) >= 0;
  1246. }
  1247.  
  1248. };
  1249.  
  1250. template <class charT, class traits, class Alloc>
  1251. std::basic_istream<charT,traits>& operator >> (std::basic_istream<charT,traits>& is,
  1252. mystd::basic_string<charT,traits,Alloc>& str)
  1253. {
  1254. str.clear(); //先清空str
  1255. int chr = 0; //对wchar_t类型字符也适用
  1256. while((chr = is.get()) && chr != ' ' && chr != '\n')
  1257. str.push_back(chr);
  1258. return is;
  1259. }
  1260.  
  1261. template <class charT, class traits, class Alloc>
  1262. std::basic_ostream<charT,traits>& operator<< (std::basic_ostream<charT,traits>& os,
  1263. const mystd::basic_string<charT,traits,Alloc>& str)
  1264. {
  1265. typedef typename mystd::basic_string<charT,traits,Alloc>::size_type size_type;
  1266. size_type size = str.size();
  1267. for(size_type i = 0; i < size; ++i)
  1268. os<<str[i];
  1269. return os;
  1270.  
  1271. }
  1272.  
  1273. template <class charT, class traits, class Alloc>
  1274. std::basic_istream<charT,traits>& getline(std::basic_istream<charT,traits>& is,
  1275. mystd::basic_string<charT,traits,Alloc>& str, charT delim)
  1276. {
  1277. charT chr = 0;
  1278. str.clear(); //先清空str
  1279. while((chr = is.get()) && chr != delim && chr != '\n')
  1280. str.push_back(chr);
  1281. return is;
  1282. }
  1283.  
  1284. template <class charT, class traits, class Alloc>
  1285. std::basic_istream<charT,traits>& getline(std::basic_istream<charT,traits>& is,
  1286. mystd::basic_string<charT,traits,Alloc>& str)
  1287. {
  1288. charT chr = 0;
  1289. str.clear(); //先清空str
  1290. while((chr = is.get()) && chr != '\n')
  1291. str.push_back(chr);
  1292. return is;
  1293. }
  1294.  
  1295. typedef mystd::basic_string<char,std::char_traits<char>,std::allocator<char> > string;
  1296. typedef mystd::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > wstring;
  1297.  
  1298. MYSTD_END // end of namespace mystd
  1299. #endif // __cplusplus
  1300. #endif // MYSTD_STRING_H_EX

以下是一个简单的測试程序!

并和标准库比对执行结果!以验证正确性。

  1. #include<iostream>
  2. #include<string>
  3. #include<ctime> //clock
  4. #include"local_string.h"
  5. #define STD mystd //改为std能够执行标准库版本号
  6.  
  7. //測试可知。结果与标准库的执行结果一样
  8.  
  9. using std::cout;
  10. using std::wcout;
  11. using std::cin;
  12. using std::wcin;
  13. using std::endl;
  14.  
  15. int main()
  16. { // 下面是一些測试代码!
  17. STD::string str;
  18. str = "ABCDEFGHIJK"; //11 个字符长度
  19.  
  20. clock_t start = clock();
  21.  
  22. //之所以选择在首部进行插入操作。是为了測试在极端条件下的执行效率。
  23. for(int i = 0; i < 25; ++i)
  24. str.insert(0,str);
  25. //完毕循环后。str会变得非常大,大小为 11乘以2的25次方 ,结果为369,098,752个字符长度
  26. clock_t finish = clock();
  27. /*
  28. 在release版本号下的统计结果例如以下:(执行时间/S)
  29. mystd | std
  30. --------------|--------------------
  31. 0.348 | 0.435
  32. 0.366 | 0.446
  33. 0.359 | 0.47
  34. 0.392 | 0.46
  35. 0.374 | 0.445
  36. 能够看到,我的实现版本号比标准库略快!
  37. 声明:我的机器是win8系统,vs2012
  38. */
  39. cout<<double(finish - start) / CLOCKS_PER_SEC << "秒"<<endl;
  40. //str.size()的结果与标准库一样,str.capacity()不一样,
  41. //这个是正常的,capacity()的结果与详细的实现有关
  42. cout<<str.size()<<"\t"<<str.capacity()<<endl;
  43. str.swap(STD::string()); //显式释放内存
  44.  
  45. //我的邮箱,希望指教!
  46. str.insert(0,"sunkang2101024@foxmail.com");
  47.  
  48. //正确的输出结果是sunkang2101024
  49. cout<<str.erase(str.find_first_of('@',0))<<endl;
  50.  
  51. //宽字符版本号測试
  52. wcout<<STD::wstring(L"hello world").c_str()<<endl;
  53. STD::wstring wstr;
  54. wstr += L"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  55.  
  56. //測试反向迭代器
  57. for(STD::wstring::const_reverse_iterator first = wstr.rbegin(); first != wstr.rend(); ++first)
  58. wcout<<*first<<"\t";
  59. cout<<endl;
  60.  
  61. //间接測试compare函数
  62. if(STD::string("hello world") == "hello world")
  63. cout<<"相等"<<endl;
  64. else
  65. cout<<"不相等"<<endl;
  66.  
  67. //測试一下replace函数
  68. cout<<str.assign("hello world").replace(6,5,str)<<endl;
  69. cout<<str.replace(str.begin(),str.end(),"sunkang2101024@foxmail.com")<<endl;
  70.  
  71. //測试重载的operator +
  72. cout<<"HHHHHHH " + str + 'A' + "ABCDEFG"<<endl;
  73.  
  74. // 測试异常
  75. try
  76. {
  77. str.clear();
  78. cout<<str.at(100)<<endl;
  79. //此时会抛出异常
  80. }
  81. catch(std::out_of_range& ex)
  82. {
  83. cout<<ex.what()<<endl;
  84. }
  85.  
  86. // 測试rfind函数
  87. str = "ABCDEFG RSTUVQXYZ";
  88. STD::string::size_type pos = str.rfind("EFG",str.size(),2);
  89. //能够试着将函数的第三个參数取一个比較大的值。比方100。
  90. //在我的这个实现版本号下,仍然会取得正确的结果。vs2012測试不行
  91. if(pos != STD::string::npos)
  92. cout<<str.substr(pos)<<endl;
  93.  
  94. cout<<endl;
  95. system("pause");
  96. return 0;
  97. }

望高手批评指正!

!谢谢!

!。

c++ string类的完整实现!!!的更多相关文章

  1. String 类实现 以及>> <<流插入/流提取运算符重载

    简单版的String类,旨在说明>> <<重载 #include <iostream> //#include <cstring>//包含char*的字符 ...

  2. java通过反射取得一个类的完整结构

    首先我们在person包中新建一个Person.java: package person; import sex.Sex; public class Person{ private String na ...

  3. c++中string类的详解

    ,<时返回-1,==时返回0  string的子串:string substr(int pos = 0,int n = npos) const;//返回pos开始的n个字符组成的字符串strin ...

  4. c++中string类的具体解释

    通过在站点上的资料搜集,得到了非常多关于string类使用方法的文档,通过对这些资料的整理和增加一些自己的代码,就得出了一份比較完整的关于string类函数有哪些和如何用的文档了! 以下先罗列出str ...

  5. 找工作String类(重点,背诵)(本质是一个类)

    一个顶层设计者眼中只有2个东西接口,类(属性,方法) 无论String 类 , HashMap实现类 , Map接口 String str = "Hello" ;    // 定义 ...

  6. 20155312张竞予 20170510实践一:在IDEA中以TDD的方式对String类和Arrays类进行学习

    实践题目 在IDEA中以TDD的方式对String类和Arrays类进行学习 测试相关方法的正常,错误和边界情况 String类 charAt split Arrays类 sort binarySea ...

  7. Scanner的概述与String类的构造和使用_DAY12

    1:Scanner的概述(理解) 1)Scanner是JDK5以后出现的方便我们从键盘接受数据的类. 2)Scanner的构造格式: Scanner sc = new Scanner(System.i ...

  8. STL之string类详解

    通过在网站上的资料搜集,得到了很多关于string类用法的文档,通过对这些资料的整理和加入一些自己的代码,就得出了一份比较完整的关于string类函数有哪些和怎样用的文档了!下面先罗列出string类 ...

  9. C++ STL介绍——String类

    目录 1.简介 2.string类成员函数汇总 3.String类的构造函数以及析构函数 4.获取字符串长度 5.获取字符串元素 6.字符串比较方法 7.字符串输入输出 8.字符串查找函数 1.简介 ...

随机推荐

  1. 自动合法打印VitalSource Bookshelf中的电子书

    最近有一本2千多页的在VitalSource中的电子书想转为PDF随时阅读,没料网上找了一圈没有找到合适的.相对好一些的只有一个用Python写的模拟手动打印.于是想到了用AutoHotkey写一个自 ...

  2. HDU 4323 Contest 3

    编辑距离,经典的了.动态规划枚举即过. #include <iostream> #include <cstdio> #include <string.h> #inc ...

  3. 【JavaEE WEB 开发】Tomcat 具体解释 Servlet 入门

    转载请注明出处 :  http://blog.csdn.net/shulianghan/article/details/47146817 一. Tomcat 下载安装配置 1. Tomcat 下载 T ...

  4. Apache shiro 笔记整理之编程式授权

    下面内容是在看了涛哥的<跟我一起学shiro> 和 视频<一头扎入进shiro> 后整理出来备忘和方便自己和其它人学习. 个人主页:http://www.itit123.cn/ ...

  5. 超便携式截屏录屏软件FastStone Capture

    超便携式截屏录屏软件FastStone Capture

  6. ES API 备忘

    本文所列的所有API在ElasticSearch文档是有详尽的说明,但它的结构组织的不太好. 这篇文章把ElasticSearch API用表格的形式供大家参考. https://www.iteblo ...

  7. nyoj--37--回文字符串(动态规划)

    回文字符串 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 所谓回文字符串,就是一个字符串,从左到右读和从右到左读是完全一样的,比如"aba".当然, ...

  8. RAC IP 地址修改

    RAC 修改IP: 版本信息: REDHAT AS5 ORACLE 11G R2, 两个节点. 修改如下: 1.修改/etc/host(rac1,rac2) 192.168.3.205   rac-s ...

  9. Redis 安装与简单示例 <第一篇>【转】

    一.Redis的安装 Redis下载地址如下:https://github.com/dmajkic/redis/downloads 解压后根据自己机器的实际情况选择32位或者64位.下载解压后图片如下 ...

  10. C# HttpHelper万能框架实现 接口

    POST请请求是使用Http协议与请求的URL进行连接,然后再写入数据,最后关闭连接的过程 方法(1) //要Post的数据 string postdate = "a=123&c=4 ...