• <STL标准库中对stack、queue、priority_queue及反向迭代器的模拟实现>——《C++初阶》


    目录

    1.模拟实现stack:

    2. 模拟实现queue

    3.模拟实现priority_queue:

    4.反向迭代器 :

    4.1  ReverseIterator.h:

    4.2  list的反向迭代器:

    4.3  vector的反向迭代器: 

     4.4 test.cpp:

    后记:●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!                                                                 ——By 作者:新晓·故知


    对于STL标准库中stack、queue、priority_queue及反向迭代器的模拟实现,简单实现常用函数接口,了解并学习迭代器的适配以及反向迭代器用到的迭代器萃取技术,模拟实现综合性高,这里只进行学习了解,具体可参见STL源码。

    1.模拟实现stack:

    简单实现常用函数接口:push、pop、top、size、empty等,附用deque等。

    (1)stack.h:

    1. #pragma once
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. using namespace std;
    8. namespace my
    9. {
    10. template<class T, class Container = deque>
    11. class stack
    12. {
    13. public:
    14. void push(const T& x)
    15. {
    16. _con.push_back(x);
    17. }
    18. void pop()
    19. {
    20. _con.pop_back();
    21. }
    22. const T& top()
    23. {
    24. return _con.back();
    25. }
    26. size_t size()
    27. {
    28. return _con.size();
    29. }
    30. bool empty()
    31. {
    32. return _con.empty();
    33. }
    34. private:
    35. Container _con;
    36. };
    37. }

    (2)test.cpp:

    1. #include"Stack.h"
    2. void test_stack()
    3. {
    4. my::stack<int> s; //附用std::deque
    5. //my::stack> s; //附用std::vector
    6. //my::stack> s; //附用std::list
    7. //my::stack s; //附用std::string,数据过大会存在截断数据丢失
    8. s.push(1);
    9. s.push(2);
    10. s.push(3);
    11. s.push(4);
    12. s.push(500);
    13. while (!s.empty())
    14. {
    15. cout << s.top() << " ";
    16. s.pop();
    17. }
    18. cout << endl;
    19. }
    20. int main()
    21. {
    22. test_stack();
    23. return 0;
    24. }

    1. #include
    2. namespace byte
    3. {
    4. template<class T, class Con = deque>
    5. //template>
    6. //template>
    7. class stack
    8. {
    9. public:
    10. stack() {}
    11. void push(const T& x) { _c.push_back(x); }
    12. void pop() { _c.pop_back(); }
    13. T& top() { return _c.back(); }
    14. const T& top()const { return _c.back(); }
    15. size_t size()const { return _c.size(); }
    16. bool empty()const { return _c.empty(); }
    17. private:
    18. Con _c;
    19. };
    20. }

    2. 模拟实现queue

     简单实现常用函数接口:push、pop、front、back、size、empty等,附用deque、list等。

    (1)Queue.h:

    1. #pragma once
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. using namespace std;
    9. namespace my
    10. {
    11. template<class T,class Container =deque>
    12. class queue
    13. {
    14. public:
    15. void push(const T& x)
    16. {
    17. _con.push_back(x);
    18. }
    19. void pop()
    20. {
    21. _con.pop_front();
    22. }
    23. const T& front()
    24. {
    25. return _con.front();
    26. }
    27. const T& back()
    28. {
    29. return _con.back();
    30. }
    31. size_t size()
    32. {
    33. return _con.size();
    34. }
    35. bool empty()
    36. {
    37. return _con.empty();
    38. }
    39. private:
    40. Container _con;
    41. };
    42. }

    (2)test.cpp:

    1. #include"Queue.h"
    2. void test_queue()
    3. {
    4. my::queue<int> q; //附用std::deque
    5. //my::queue> q; //附用std::list
    6. q.push(1);
    7. q.push(2);
    8. q.push(3);
    9. q.push(4);
    10. while (!q.empty())
    11. {
    12. cout << q.front() << " ";
    13. q.pop();
    14. }
    15. cout << endl;
    16. }
    17. int main()
    18. {
    19. test_queue();
    20. return 0;
    21. }

    1. #include
    2. #include
    3. namespace byte
    4. {
    5. template<class T, class Con = deque>
    6. //template>
    7. class queue
    8. {
    9. public:
    10. queue() {}
    11. void push(const T& x) { _c.push_back(x); }
    12. void pop() { _c.pop_front(); }
    13. T& back() { return _c.back(); }
    14. const T& back()const { return _c.back(); }
    15. T& front() { return _c.front(); }
    16. const T& front()const { return _c.front(); }
    17. size_t size()const { return _c.size(); }
    18. bool empty()const { return _c.empty(); }
    19. private:
    20. Con _c;
    21. };
    22. }

    3.模拟实现priority_queue:

    简单实现常用函数接口:push、pop、top、size、empty等,附用deque等。对于priority_queue模拟实现,还涉及仿函数less 、greater调整优先级,建立堆以及堆的调整,综合性高。

    (1)priority_queue:

    1. #pragma once
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. using namespace std;
    10. //仿函数版1
    11. //namespace my
    12. //{
    13. // A
    14. // 仿函数/函数对象 --对象可以像调用函数一样去使用
    15. // //struct less
    16. // //{
    17. // // bool operator()(int x, int y)
    18. // // {
    19. // // return x < y;
    20. // // }
    21. // //};
    22. //
    23. // //可比较不同类型,int,double等
    24. // //仿函数less
    25. // template
    26. // struct less
    27. // {
    28. // bool operator()(const T& x, const T& y) const
    29. // {
    30. // return x < y;
    31. // }
    32. // };
    33. // //仿函数greater
    34. // template
    35. // struct greater
    36. // {
    37. // bool operator()(const T& x, const T& y) const
    38. // {
    39. // return x > y;
    40. // }
    41. // };
    42. // //仿函数可以替代函数指针
    43. //
    44. // //优先级队列: 大堆用< 小堆用>
    45. // template,class Compare=less>
    46. // class priority_queue
    47. // {
    48. // public:
    49. // void AdjustUp(int child)
    50. // {
    51. // Compare comFunc;
    52. // int parent = (child - 1) / 2;
    53. // while (child > 0)
    54. // {
    55. // //if (_con[parent] < _con[child])
    56. // if(comFunc(_con[parent], _con[child])) //if (comFunc.operator()(_con[parent], _con[child]))
    57. // {
    58. // swap(_con[parent], _con[child]);
    59. // child = parent;
    60. // parent = (child - 1) / 2;
    61. // }
    62. // else
    63. // {
    64. // break;
    65. // }
    66. // }
    67. // }
    68. // void push(const T& x)
    69. // {
    70. // _con.push_back(x);
    71. // AdjustUp(_con.size() - 1);
    72. //
    73. // }
    74. // void AdjustDown(int parent)
    75. // {
    76. // Compare comFunc;
    77. //
    78. // size_t child = parent * 2 + 1;
    79. // while (child<_con.size())
    80. // {
    81. // //if (child + 1 < _con.size() && _con[child] < _con[child + 1])
    82. // if (child + 1 < _con.size() &&comFunc(_con[child], _con[child + 1]))
    83. // {
    84. // ++child;
    85. // }
    86. // //if (_con[parent]<_con[child])
    87. // if (comFunc(_con[parent] ,_con[child]))
    88. // {
    89. // swap(_con[parent], _con[child]);
    90. // parent = child;
    91. // child = parent * 2 + 1;
    92. // }
    93. // else
    94. // {
    95. // break;
    96. // }
    97. // }
    98. // }
    99. // void pop()
    100. // {
    101. // assert(!_con.empty());
    102. // swap(_con[0], _con[_con.size() - 1]);
    103. // _con.pop_back();
    104. //
    105. // AdjustDown(0);
    106. // }
    107. // const T& top()
    108. // {
    109. // return _con[0];
    110. // }
    111. // size_t size()
    112. // {
    113. // return _con.size();
    114. // }
    115. // bool empty()
    116. // {
    117. // return _con.empty();
    118. // }
    119. // private:
    120. // Container _con;
    121. // };
    122. //}
    123. 函数指针版
    124. //namespace my
    125. //{
    126. // bool ComIntLess(int x1, int x2)
    127. // {
    128. // return x1 > x2;
    129. // }
    130. // //仿函数less
    131. // template
    132. // struct less
    133. // {
    134. // bool operator()(const T& x, const T& y) const
    135. // {
    136. // return x < y;
    137. // }
    138. // };
    139. // //仿函数greater
    140. // template
    141. // struct greater
    142. // {
    143. // bool operator()(const T& x, const T& y) const
    144. // {
    145. // return x > y;
    146. // }
    147. // };
    148. //
    149. // //template, class Compare = less>
    150. // template, class Compare = less>
    151. //
    152. // class priority_queue
    153. // {
    154. // public:
    155. // priority_queue(const Compare& comFunc = Compare())
    156. // :_comFunc(comFunc)
    157. //
    158. // {}
    159. // void AdjustUp(int child)
    160. // {
    161. // //Compare comFunc;
    162. // int parent = (child - 1) / 2;
    163. // while (child > 0)
    164. // {
    165. // //if (_con[parent] < _con[child])
    166. // if (_comFunc(_con[parent], _con[child])) //if (comFunc.operator()(_con[parent], _con[child]))
    167. // {
    168. // swap(_con[parent], _con[child]);
    169. // child = parent;
    170. // parent = (child - 1) / 2;
    171. // }
    172. // else
    173. // {
    174. // break;
    175. // }
    176. // }
    177. // }
    178. // void push(const T& x)
    179. // {
    180. // _con.push_back(x);
    181. // AdjustUp(_con.size() - 1);
    182. //
    183. // }
    184. // void AdjustDown(int parent)
    185. // {
    186. // Compare comFunc;
    187. //
    188. // size_t child = parent * 2 + 1;
    189. // while (child < _con.size())
    190. // {
    191. // //if (child + 1 < _con.size() && _con[child] < _con[child + 1])
    192. // if (child + 1 < _con.size() && _comFunc(_con[child], _con[child + 1]))
    193. // {
    194. // ++child;
    195. // }
    196. // //if (_con[parent]<_con[child])
    197. // if (_comFunc(_con[parent], _con[child]))
    198. // {
    199. // swap(_con[parent], _con[child]);
    200. // parent = child;
    201. // child = parent * 2 + 1;
    202. // }
    203. // else
    204. // {
    205. // break;
    206. // }
    207. // }
    208. // }
    209. // void pop()
    210. // {
    211. // assert(!_con.empty());
    212. // swap(_con[0], _con[_con.size() - 1]);
    213. // _con.pop_back();
    214. //
    215. // AdjustDown(0);
    216. // }
    217. // const T& top()
    218. // {
    219. // return _con[0];
    220. // }
    221. // size_t size()
    222. // {
    223. // return _con.size();
    224. // }
    225. // bool empty()
    226. // {
    227. // return _con.empty();
    228. // }
    229. // private:
    230. // Compare _comFunc;
    231. // Container _con;
    232. // };
    233. //}
    234. //仿函数版2
    235. namespace my
    236. {
    237. A
    238. 仿函数/函数对象 --对象可以像调用函数一样去使用
    239. //struct less
    240. //{
    241. // bool operator()(int x, int y)
    242. // {
    243. // return x < y;
    244. // }
    245. //};
    246. //可比较不同类型,int,double等
    247. //仿函数less
    248. template<class T>
    249. struct less
    250. {
    251. bool operator()(const T& x, const T& y) const
    252. {
    253. return x < y;
    254. }
    255. };
    256. //仿函数greater
    257. template<class T>
    258. struct greater
    259. {
    260. bool operator()(const T& x, const T& y) const
    261. {
    262. return x > y;
    263. }
    264. };
    265. //仿函数可以替代函数指针
    266. //优先级队列: 大堆用< 小堆用>
    267. template<class T, class Container = vector, class Compare = less>
    268. class priority_queue
    269. {
    270. public:
    271. priority_queue(const Compare& comFunc = Compare())
    272. :_comFunc(comFunc)
    273. {}
    274. template <class InputIterator>
    275. priority_queue(InputIterator first, InputIterator last,
    276. const Compare& comFunc = Compare())
    277. :_comFunc(comFunc)
    278. {
    279. while (first != last)
    280. {
    281. _con.push_back(*first);
    282. ++first;
    283. }
    284. //建堆(倒着建)
    285. for (int i = (_con.size() - 1 - 1) / 2; i >= 0; --i)
    286. {
    287. AdjustDown(i);
    288. }
    289. }
    290. void AdjustUp(int child)
    291. {
    292. Compare comFunc;
    293. int parent = (child - 1) / 2;
    294. while (child > 0)
    295. {
    296. //if (_con[parent] < _con[child])
    297. if (comFunc(_con[parent], _con[child])) //if (comFunc.operator()(_con[parent], _con[child]))
    298. {
    299. swap(_con[parent], _con[child]);
    300. child = parent;
    301. parent = (child - 1) / 2;
    302. }
    303. else
    304. {
    305. break;
    306. }
    307. }
    308. }
    309. void push(const T& x)
    310. {
    311. _con.push_back(x);
    312. AdjustUp(_con.size() - 1);
    313. }
    314. void AdjustDown(int parent)
    315. {
    316. Compare comFunc;
    317. size_t child = parent * 2 + 1;
    318. while (child < _con.size())
    319. {
    320. //if (child + 1 < _con.size() && _con[child] < _con[child + 1])
    321. if (child + 1 < _con.size() && comFunc(_con[child], _con[child + 1]))
    322. {
    323. ++child;
    324. }
    325. //if (_con[parent]<_con[child])
    326. if (comFunc(_con[parent], _con[child]))
    327. {
    328. swap(_con[parent], _con[child]);
    329. parent = child;
    330. child = parent * 2 + 1;
    331. }
    332. else
    333. {
    334. break;
    335. }
    336. }
    337. }
    338. void pop()
    339. {
    340. assert(!_con.empty());
    341. swap(_con[0], _con[_con.size() - 1]);
    342. _con.pop_back();
    343. AdjustDown(0);
    344. }
    345. const T& top()
    346. {
    347. return _con[0];
    348. }
    349. size_t size()
    350. {
    351. return _con.size();
    352. }
    353. bool empty()
    354. {
    355. return _con.empty();
    356. }
    357. private:
    358. Compare _comFunc;
    359. Container _con;
    360. };
    361. }

    (2)test.cpp:

    1. #include"priority_queue.h"
    2. //仿函数版1测试
    3. //void test_priority_queue()
    4. //{
    5. // //问题:优先级队列(priority_queue)默认大的优先级高,但传的是less仿函数<,底层是一个大堆
    6. // //如果想切换成小的优先级高,则传greater仿函数,底层是一个小堆,
    7. // //这种设计是反过来的,设计有些违反常规
    8. // //my::priority_queue pq; //默认是大堆 less比较<
    9. // my::priority_queue, my::greater> pq; //greater 仿函数,默认小的优先级高,这里为小堆
    10. // pq.push(6);
    11. // pq.push(4);
    12. // pq.push(7);
    13. // pq.push(3);
    14. // pq.push(1);
    15. // pq.push(9);
    16. // while (!pq.empty())
    17. // {
    18. // cout << pq.top() << " ";
    19. // pq.pop();
    20. // }
    21. // cout << endl;
    22. //}
    23. //仿函数less测试
    24. //这个测试对应于A
    25. void test_less_function()
    26. {
    27. my::less LessCom;
    28. cout << LessCom(6, 9) << endl; //lessCom是一个less对象,less是仿函数,
    29. }
    30. 仿函数less测试
    31. 这个测试对应于templ
    32. //void test_function()
    33. //{
    34. // //可比较不同类型,int,double等
    35. // my::less LessCom;
    36. // cout << LessCom(6, 9) << endl; //LessCom是less的对象,虽然看着像函数调用,但其实是对象
    37. //
    38. // my::greater GreaterCom;
    39. // cout << GreaterCom(1.1, 5.4) << endl;
    40. //}
    41. //int main()
    42. //{
    43. // test_priority_queue();
    44. // //test_less_function();
    45. // //test_function();
    46. // return 0;
    47. //}
    48. //函数指针版测试
    49. //void test_priority_queue()
    50. //{
    51. // bool my::ComIntLess(int x1, int x2);
    52. // //my::priority_queue pq;
    53. // //my::priority_queue, my::greater> pq;
    54. // my::priority_queue, bool(*)(int,int)> pq(my::ComIntLess); //函数名当做函数指针传过去
    55. // pq.push(6);
    56. // pq.push(4);
    57. // pq.push(7);
    58. // pq.push(3);
    59. // pq.push(1);
    60. // pq.push(9);
    61. // while (!pq.empty())
    62. // {
    63. // cout << pq.top() << " ";
    64. // pq.pop();
    65. // }
    66. // cout << endl;
    67. //
    68. //}
    69. //
    70. //
    71. //int main()
    72. //{
    73. // test_priority_queue();
    74. // return 0;
    75. //}
    76. //仿函数版2测试
    77. void test_priority_queue1()
    78. {
    79. //问题:优先级队列(priority_queue)默认大的优先级高,但传的是less仿函数<,底层是一个大堆
    80. //如果想切换成小的优先级高,则传greater仿函数,底层是一个小堆,
    81. //这种设计是反过来的,设计有些违反常规
    82. //my::priority_queue pq; //默认是大堆 less比较<
    83. my::priority_queue<int, std::vector<int>, my::greater<int>> pq; //greater 仿函数,默认小的优先级高,这里为小堆
    84. pq.push(6);
    85. pq.push(4);
    86. pq.push(7);
    87. pq.push(3);
    88. pq.push(1);
    89. pq.push(9);
    90. while (!pq.empty())
    91. {
    92. cout << pq.top() << " ";
    93. pq.pop();
    94. }
    95. cout << endl;
    96. }
    97. void test_function1()
    98. {
    99. //std::vector v;
    100. //v.push_back(3);
    101. //v.push_back(6);
    102. //v.push_back(9);
    103. //v.push_back(1);
    104. //v.push_back(5);
    105. //v.push_back(2);
    106. //for (auto e : v)
    107. //{
    108. // cout << e << " ";
    109. //}
    110. //cout << endl;
    111. //std::sort(v.begin(), v.end()); //默认升序,但调用less仿函数,与priority_queue 的仿函数顺序不一样
    112. //for (auto e : v)
    113. //{
    114. // cout << e << " ";
    115. //}
    116. //cout << endl;
    117. //std::sort(v.begin(), v.end(),greater()); //降序,但调用greater仿函数,与priority_queue 的仿函数顺序不一样
    118. //for (auto e : v) //这里greater传的是匿名对象
    119. //{
    120. // cout << e << " ";
    121. //}
    122. //cout << endl;
    123. //给数组排序
    124. //指向数组的原生指针,本身就是天然的迭代器
    125. int a[6] = { 2,7,5,9,6,3 };
    126. for (auto e : a)
    127. {
    128. cout << e << " ";
    129. }
    130. cout << endl;
    131. std::sort(a, a + 6); //默认升序
    132. for (auto e : a)
    133. {
    134. cout << e << " ";
    135. }
    136. cout << endl;
    137. std::sort(a, a + 6, greater<int>()); //降序,这里greater传的是匿名对象,
    138. for (auto e : a)
    139. {
    140. cout << e << " ";
    141. }
    142. cout << endl;
    143. }
    144. //struct Goods
    145. //{
    146. // /*bool operator<(const Goods& g)const
    147. // {
    148. // return _price < g._price;
    149. // }*/
    150. // // 多种方式比较,运算符重载就不适用,可以使用仿函数
    151. //
    152. // string _name;
    153. // double _price;
    154. // size_t _saleNum;
    155. //
    156. //};
    157. 输入输出流运算符重载
    158. //std::ostream& operator<<(std::ostream& out, const Goods& g)
    159. //{
    160. // out << g._name <<" " << g._price <<" " << g._saleNum << endl;
    161. // return out;
    162. //}
    163. //std::istream& operator>>(std::istream& in, Goods& g)
    164. //{
    165. // in>> g._name >> g._price >> g._saleNum;
    166. // return in;
    167. //}
    168. //struct LessPrice
    169. //{
    170. // bool operator()(const Goods& g1,const Goods& g2)const
    171. // {
    172. // return g1._price < g2._price;
    173. // }
    174. //
    175. //};
    176. //struct GreaterPrice
    177. //{
    178. // bool operator()(const Goods& g1, const Goods& g2)const
    179. // {
    180. // return g1._price > g2._price;
    181. // }
    182. //};
    183. //
    184. //struct LessSaleNum
    185. //{
    186. // bool operator()(const Goods& g1, const Goods& g2)const
    187. // {
    188. // return g1._saleNum
    189. // }
    190. //};
    191. //struct GreaterSaleNum
    192. //{
    193. // bool operator()(const Goods& g1, const Goods& g2)const
    194. // {
    195. // return g1._saleNum > g2._saleNum;
    196. // }
    197. //};
    198. //
    199. //void test_function2()
    200. //{
    201. // Goods gds[] = { { "苹果", 2.1 ,100}, { "香蕉", 3 ,211}, { "橙子", 2.2,200 }, {"菠萝", 1.5,190} };
    202. // sort(gds, gds + sizeof(gds) / sizeof(gds[0]),LessPrice());
    203. // for (auto e : gds)
    204. // {
    205. // cout << e;
    206. // }
    207. // cout << endl;
    208. // sort(gds, gds + sizeof(gds) / sizeof(gds[0]), GreaterPrice());
    209. // for (auto e : gds)
    210. // {
    211. // cout << e;
    212. // }
    213. // cout << endl;
    214. // sort(gds, gds + sizeof(gds) / sizeof(gds[0]), LessSaleNum());
    215. // for (auto e : gds)
    216. // {
    217. // cout << e;
    218. // }
    219. // cout << endl;
    220. // sort(gds, gds + sizeof(gds) / sizeof(gds[0]),GreaterSaleNum());
    221. // for (auto e : gds)
    222. // {
    223. // cout << e ;
    224. // }
    225. // cout << endl;
    226. //}
    227. //建堆测试
    228. void test_priority_queue2()
    229. {
    230. int a[] = { 2,7,5,9,8,2,1 };
    231. //my::priority_queue pq(a, a + 7);
    232. my::priority_queue<int, std::vector<int>, my::greater<int>> pq(a, a + 7);
    233. cout << pq.top()<
    234. }
    235. int main()
    236. {
    237. //test_priority_queue1();
    238. //test_function1();
    239. //test_function2();
    240. test_priority_queue2();
    241. return 0;
    242. }

    4.反向迭代器 :

    与正向迭代器相比,除了++、--时方向相反,其他操作基本一致

    扩展:迭代器萃取技术。

    对于反向迭代器的模拟实现其实涉及到许多综合性实现,比如模板(只传模板参数、传多个参数),传不同参数实现用到的技术也不一样,而对于STL标准库里的实现则涉及到迭代器的萃取,这里只做简单学习了解,具体可参见STL源码。

    以下则模拟实现了模板(只传模板参数、传多个参数)两个版本,但实际应用中,建议使用传多个参数。

     

     

     

     

    4.1  ReverseIterator.h:

    1. #pragma once
    2. //显示传3个参数
    3. namespace my
    4. {
    5. template<class Iterator,class Ref,class Ptr>
    6. struct Reverse_iterator
    7. {
    8. Iterator _it;
    9. typedef Reverse_iteratorSelf;
    10. Reverse_iterator(Iterator it)
    11. :_it(it)
    12. {}
    13. Ref operator*()
    14. {
    15. Iterator tmp = _it;
    16. return *(--tmp);
    17. }
    18. Ptr operator->()
    19. {
    20. return &(operator*());
    21. }
    22. Self& operator++()
    23. {
    24. --_it;
    25. return *this;
    26. }
    27. Self& operator--()
    28. {
    29. ++_it;
    30. return *this;
    31. }
    32. bool operator!=(const Self& s)
    33. {
    34. return _it != s._it;
    35. }
    36. };
    37. }
    38. 只传迭代器
    39. //namespace my
    40. //{
    41. // template
    42. // struct Reverse_iterator
    43. // {
    44. // Iterator _it;
    45. // typedef Reverse_iteratorSelf;
    46. // //萃取
    47. // typedef typename Iterator::reference reference;
    48. // typedef typename Iterator::pointer pointer;
    49. // Reverse_iterator(Iterator it)
    50. // :_it(it)
    51. // {}
    52. // //类模板、模板虚拟类型 在没有实例化之前不能去它里面找内嵌定义的类型
    53. // //否则,类模板没有实例化,找出来的也是虚拟类型,后期无法处理
    54. // //typename会告诉编译器后面这一块是一个类型,等Iterator实例化以后,再去它里面找这个内嵌类型
    55. // //非萃取写法
    56. // /*typename Iterator::reference operator*()
    57. // {
    58. // Iterator tmp = _it;
    59. // return *(--tmp);
    60. // }
    61. //
    62. // typename Iterator::pointer operator->()
    63. // {
    64. // return &(operator*());
    65. // }*/
    66. // //萃取写法:
    67. // reference operator*()
    68. // {
    69. // Iterator tmp = _it;
    70. // return *(--tmp);
    71. // }
    72. //
    73. // pointer operator->()
    74. // {
    75. // return &(operator*());
    76. // }
    77. //
    78. // Self& operator++()
    79. // {
    80. // --_it;
    81. // return *this;
    82. // }
    83. // Self& operator--()
    84. // {
    85. // ++_it;
    86. // return *this;
    87. // }
    88. // bool operator!=(const Self& s)
    89. // {
    90. // return _it != s._it;
    91. // }
    92. // };
    93. //}

    4.2  list的反向迭代器:

    1. //反向迭代器传3个参数
    2. #pragma once
    3. #include
    4. #include
    5. #include
    6. #include"ReverseIterator.h"
    7. using namespace std;
    8. //自定义命名空间,防止与库里的冲突
    9. namespace my
    10. {
    11. template<class T>
    12. struct list_node
    13. {
    14. list_node* _next;
    15. list_node* _prev;
    16. T _data;
    17. list_node(const T& val) //或A:给个缺省值list_node(const T& val=T())
    18. :_next(nullptr)
    19. , _prev(nullptr)
    20. , _data(val)
    21. {}
    22. };
    23. template<class T, class Ref, class Ptr> //多个模板参数
    24. struct __list_iterator
    25. {
    26. typedef list_node Node;
    27. typedef __list_iterator self;
    28. Node* _node;
    29. __list_iterator(Node* node)
    30. :_node(node)
    31. {}
    32. Ref operator*()
    33. {
    34. return _node->_data;
    35. }
    36. self& operator++() //默认为前置++
    37. {
    38. _node = _node->_next;
    39. return *this;
    40. }
    41. self& operator++(int) //后置++
    42. {
    43. self tmp(*this);
    44. _node = _node->_next;
    45. return tmp;
    46. }
    47. self& operator--() //前置--
    48. {
    49. _node = _node->_prev;
    50. return *this;
    51. }
    52. self& operator--(int) //后置--
    53. {
    54. self tmp(*this);
    55. _node = _node->_prev;
    56. return tmp;
    57. }
    58. bool operator!=(const self& it)
    59. {
    60. return _node != it._node;
    61. }
    62. bool operator==(const self& it)
    63. {
    64. return _node == it._node;
    65. }
    66. //"->"重载
    67. Ptr operator->()
    68. {
    69. return &(operator*());//等价于return &_node->_data;
    70. }
    71. };
    72. template<class T>
    73. class list
    74. {
    75. typedef list_node Node;
    76. public:
    77. typedef __list_iterator iterator;
    78. typedef __list_iteratorconst T&, const T*> const_iterator;
    79. //反向迭代器适配支持
    80. typedef Reverse_iteratorreverse_iterator;
    81. typedef Reverse_iteratorconst T&, const T*>const_reverse_iterator;
    82. reverse_iterator rbegin()
    83. {
    84. return reverse_iterator(end());
    85. }
    86. reverse_iterator rend()
    87. {
    88. return reverse_iterator(begin());
    89. }
    90. const_reverse_iterator rbegin() const
    91. {
    92. return const_reverse_iterator(end());
    93. }
    94. const_reverse_iterator rend() const
    95. {
    96. return const_reverse_iterator(begin());
    97. }
    98. //迭代器
    99. iterator begin()
    100. {
    101. return iterator(_head->_next);
    102. }
    103. iterator end()
    104. {
    105. return iterator(_head);
    106. }
    107. //const迭代器:多模板参数,附用普通迭代器
    108. const_iterator begin() const
    109. {
    110. return const_iterator(_head->_next);
    111. }
    112. const_iterator end() const
    113. {
    114. return const_iterator(_head);
    115. }
    116. //构造函数
    117. list()
    118. {
    119. _head = new Node(T()); //或A:_head = new Node(); A对应上面的A语句
    120. _head->_next = _head;
    121. _head->_prev = _head;
    122. }
    123. //析构函数
    124. ~list()
    125. {
    126. clear();
    127. delete _head;
    128. _head = nullptr;
    129. }
    130. //lt2(lt1)
    131. //构造函数传统写法
    132. //list(const list& lt)
    133. //{
    134. // _head = new Node(T()); //或A:_head = new Node(); A对应上面的A语句
    135. // _head->_next = _head;
    136. // _head->_prev = _head;
    137. // for (auto e : lt)
    138. // {
    139. // push_back(e);
    140. // }
    141. //}
    142. //初始化
    143. void empty_init()
    144. {
    145. _head = new Node(T()); //或A:_head = new Node(); A对应上面的A语句
    146. _head->_next = _head;
    147. _head->_prev = _head;
    148. }
    149. template <class InputIterator>
    150. list(InputIterator first, InputIterator last)
    151. {
    152. empty_init();
    153. while (first != last)
    154. {
    155. push_back(*first);
    156. ++first;
    157. }
    158. }
    159. //交换
    160. void swap(list& lt)
    161. {
    162. std::swap(_head, lt._head);
    163. }
    164. //构造函数——现代写法
    165. list(const list& lt)
    166. {
    167. empty_init();
    168. list tmp(lt.begin(), lt.end());
    169. swap(tmp);
    170. }
    171. //赋值重载——现代写法
    172. list& operator=(list lt)
    173. {
    174. swap(lt);
    175. return *this;
    176. }
    177. void clear() //clear清理数据,结构还在
    178. {
    179. iterator it = begin();
    180. while (it != end())
    181. {
    182. it = erase(it);
    183. }
    184. }
    185. //尾插
    186. void push_back(const T& x)
    187. {
    188. /*Node* tail = _head->_prev;
    189. Node* newnode = new Node(x);
    190. tail->_next = newnode;
    191. newnode->_prev = tail;
    192. newnode->_next = _head;
    193. _head->_prev = newnode;*/
    194. //附用insert
    195. insert(end(), x);
    196. }
    197. //头插
    198. void push_front(const T& x)
    199. {
    200. insert(begin(), x);
    201. }
    202. //insert插入在pos位置之前
    203. iterator insert(iterator pos, const T& x)
    204. {
    205. Node* newNode = new Node(x);
    206. Node* cur = pos._node;
    207. Node* prev = cur->_prev;
    208. prev->_next = newNode;
    209. newNode->_prev = prev;
    210. newNode->_next = cur;
    211. cur->_prev = newNode;
    212. return iterator(newNode);
    213. }
    214. //尾删
    215. void pop_back()
    216. {
    217. erase(--end());
    218. }
    219. //头删
    220. void pop_front()
    221. {
    222. erase(begin());
    223. }
    224. //删除
    225. iterator erase(iterator pos)
    226. {
    227. assert(pos != end());
    228. Node* cur = pos._node;
    229. Node* prev = cur->_prev;
    230. Node* next = cur->_next;
    231. prev->_next = next;
    232. next->_prev = prev;
    233. delete cur;
    234. return iterator(next);
    235. }
    236. //总结:list::insert不存在迭代器失效问题
    237. //list::erase存在野指针导致的迭代器失效
    238. private:
    239. Node* _head;
    240. };
    241. }
    242. //反向迭代器
    243. //与正向迭代器相比,除了++、--时方向相反,其他操作基本一致
    244. 只传迭代器(list只传迭代器,勉强能实现运行,但vector只传迭代器就比较复杂)
    245. //#pragma once
    246. //#include
    247. //#include
    248. //#include
    249. //#include"ReverseIterator.h"
    250. //using namespace std;
    251. //
    252. 自定义命名空间,防止与库里的冲突
    253. //namespace my
    254. //{
    255. // template
    256. // struct list_node
    257. // {
    258. // list_node* _next;
    259. // list_node* _prev;
    260. // T _data;
    261. //
    262. // list_node(const T& val) //或A:给个缺省值list_node(const T& val=T())
    263. // :_next(nullptr)
    264. // , _prev(nullptr)
    265. // , _data(val)
    266. // {}
    267. // };
    268. // template //多个模板参数
    269. // struct __list_iterator
    270. // {
    271. // typedef list_node Node;
    272. // typedef __list_iterator self;
    273. // typedef Ref reference;
    274. // typedef Ptr pointer;
    275. // Node* _node;
    276. // __list_iterator(Node* node)
    277. // :_node(node)
    278. // {}
    279. // Ref operator*()
    280. // {
    281. // return _node->_data;
    282. // }
    283. // self& operator++() //默认为前置++
    284. // {
    285. // _node = _node->_next;
    286. // return *this;
    287. // }
    288. // self& operator++(int) //后置++
    289. // {
    290. // self tmp(*this);
    291. // _node = _node->_next;
    292. // return tmp;
    293. // }
    294. // self& operator--() //前置--
    295. // {
    296. // _node = _node->_prev;
    297. // return *this;
    298. // }
    299. // self& operator--(int) //后置--
    300. // {
    301. // self tmp(*this);
    302. // _node = _node->_prev;
    303. // return tmp;
    304. // }
    305. // bool operator!=(const self& it)
    306. // {
    307. // return _node != it._node;
    308. // }
    309. // bool operator==(const self& it)
    310. // {
    311. // return _node == it._node;
    312. // }
    313. // //"->"重载
    314. // Ptr operator->()
    315. // {
    316. // return &(operator*());//等价于return &_node->_data;
    317. // }
    318. //
    319. // };
    320. //
    321. //
    322. // template
    323. // class list
    324. // {
    325. // typedef list_node Node;
    326. // public:
    327. // typedef __list_iterator iterator;
    328. // typedef __list_iterator const_iterator;
    329. //
    330. // //反向迭代器适配支持
    331. // typedef Reverse_iteratorreverse_iterator;
    332. // typedef Reverse_iteratorconst_reverse_iterator;
    333. //
    334. // reverse_iterator rbegin()
    335. // {
    336. // return reverse_iterator(end());
    337. // }
    338. // reverse_iterator rend()
    339. // {
    340. // return reverse_iterator(begin());
    341. // }
    342. // const_reverse_iterator rbegin() const
    343. // {
    344. // return const_reverse_iterator(end());
    345. // }
    346. // const_reverse_iterator rend() const
    347. // {
    348. // return const_reverse_iterator(begin());
    349. // }
    350. //
    351. // //迭代器
    352. // iterator begin()
    353. // {
    354. // return iterator(_head->_next);
    355. // }
    356. // iterator end()
    357. // {
    358. // return iterator(_head);
    359. // }
    360. // //const迭代器:多模板参数,附用普通迭代器
    361. // const_iterator begin() const
    362. // {
    363. // return const_iterator(_head->_next);
    364. // }
    365. // const_iterator end() const
    366. // {
    367. // return const_iterator(_head);
    368. // }
    369. //
    370. // //构造函数
    371. // list()
    372. // {
    373. // _head = new Node(T()); //或A:_head = new Node(); A对应上面的A语句
    374. //
    375. // _head->_next = _head;
    376. // _head->_prev = _head;
    377. // }
    378. // //析构函数
    379. // ~list()
    380. // {
    381. // clear();
    382. // delete _head;
    383. // _head = nullptr;
    384. // }
    385. // //lt2(lt1)
    386. // //构造函数传统写法
    387. // //list(const list& lt)
    388. // //{
    389. // // _head = new Node(T()); //或A:_head = new Node(); A对应上面的A语句
    390. // // _head->_next = _head;
    391. // // _head->_prev = _head;
    392. // // for (auto e : lt)
    393. // // {
    394. // // push_back(e);
    395. // // }
    396. // //}
    397. // //初始化
    398. // void empty_init()
    399. // {
    400. // _head = new Node(T()); //或A:_head = new Node(); A对应上面的A语句
    401. // _head->_next = _head;
    402. // _head->_prev = _head;
    403. // }
    404. //
    405. // template
    406. // list(InputIterator first, InputIterator last)
    407. // {
    408. // empty_init();
    409. // while (first != last)
    410. // {
    411. // push_back(*first);
    412. // ++first;
    413. // }
    414. // }
    415. // //交换
    416. // void swap(list& lt)
    417. // {
    418. // std::swap(_head, lt._head);
    419. // }
    420. // //构造函数——现代写法
    421. // list(const list& lt)
    422. // {
    423. // empty_init();
    424. // list tmp(lt.begin(), lt.end());
    425. // swap(tmp);
    426. // }
    427. // //赋值重载——现代写法
    428. // list& operator=(list lt)
    429. // {
    430. // swap(lt);
    431. // return *this;
    432. // }
    433. // void clear() //clear清理数据,结构还在
    434. // {
    435. // iterator it = begin();
    436. // while (it != end())
    437. // {
    438. // it = erase(it);
    439. // }
    440. // }
    441. // //尾插
    442. // void push_back(const T& x)
    443. // {
    444. // /*Node* tail = _head->_prev;
    445. // Node* newnode = new Node(x);
    446. //
    447. // tail->_next = newnode;
    448. // newnode->_prev = tail;
    449. // newnode->_next = _head;
    450. // _head->_prev = newnode;*/
    451. // //附用insert
    452. // insert(end(), x);
    453. // }
    454. // //头插
    455. // void push_front(const T& x)
    456. // {
    457. // insert(begin(), x);
    458. // }
    459. // //insert插入在pos位置之前
    460. // iterator insert(iterator pos, const T& x)
    461. // {
    462. // Node* newNode = new Node(x);
    463. // Node* cur = pos._node;
    464. // Node* prev = cur->_prev;
    465. // prev->_next = newNode;
    466. // newNode->_prev = prev;
    467. // newNode->_next = cur;
    468. // cur->_prev = newNode;
    469. // return iterator(newNode);
    470. // }
    471. // //尾删
    472. // void pop_back()
    473. // {
    474. // erase(--end());
    475. // }
    476. // //头删
    477. // void pop_front()
    478. // {
    479. // erase(begin());
    480. // }
    481. // //删除
    482. // iterator erase(iterator pos)
    483. // {
    484. // assert(pos != end());
    485. // Node* cur = pos._node;
    486. // Node* prev = cur->_prev;
    487. // Node* next = cur->_next;
    488. // prev->_next = next;
    489. // next->_prev = prev;
    490. // delete cur;
    491. // return iterator(next);
    492. // }
    493. // //总结:list::insert不存在迭代器失效问题
    494. // //list::erase存在野指针导致的迭代器失效
    495. // private:
    496. // Node* _head;
    497. // };
    498. //
    499. //}
    500. //
    501. //
    502. 反向迭代器
    503. 与正向迭代器相比,除了++、--时方向相反,其他操作基本一致

    4.3  vector的反向迭代器: 

    1. //反向迭代器传3个参数
    2. #pragma once
    3. //模拟实现vector
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include"ReverseIterator.h"
    9. using namespace std;
    10. //自定义命名空间,防止与库里的冲突
    11. namespace my
    12. {
    13. template<class T>
    14. class vector
    15. {
    16. public:
    17. typedef T* iterator;
    18. typedef const T* const_iterator;
    19. //反向迭代器适配支持
    20. typedef Reverse_iteratorreverse_iterator;
    21. typedef Reverse_iteratorconst T&, const T*>const_reverse_iterator;
    22. reverse_iterator rbegin()
    23. {
    24. return reverse_iterator(end());
    25. }
    26. reverse_iterator rend()
    27. {
    28. return reverse_iterator(begin());
    29. }
    30. const_reverse_iterator rbegin() const
    31. {
    32. return const_reverse_iterator(end());
    33. }
    34. const_reverse_iterator rend() const
    35. {
    36. return const_reverse_iterator(begin());
    37. }
    38. //构造函数
    39. vector()
    40. :_start(nullptr)
    41. , _finish(nullptr)
    42. , _endofstorage(nullptr)
    43. {}
    44. //使用n个val构造函数
    45. vector(size_t n, const T& val = T())
    46. :_start(nullptr)
    47. , _finish(nullptr)
    48. , _endofstorage(nullptr)
    49. {
    50. reserve(n);
    51. for (size_t i = 0; i < n; ++i)
    52. {
    53. push_back(val);
    54. }
    55. }
    56. vector(int n, const T& val = T())
    57. :_start(nullptr)
    58. , _finish(nullptr)
    59. , _endofstorage(nullptr)
    60. {
    61. reserve(n);
    62. for (size_t i = 0; i < n; ++i)
    63. {
    64. push_back(val);
    65. }
    66. }
    67. //类模板,类构造
    68. template<class InputIterator>
    69. vector(InputIterator first, InputIterator last)
    70. : _start(nullptr)
    71. , _finish(nullptr)
    72. , _endofstorage(nullptr)
    73. {
    74. while (first != last)
    75. {
    76. push_back(*first);
    77. ++first;
    78. }
    79. }
    80. void swap(vector& v)
    81. {
    82. std::swap(_start, v._start);
    83. std::swap(_finish, v._finish);
    84. std::swap(_endofstorage, v._endofstorage);
    85. }
    86. //拷贝构造函数(使用现代写法)
    87. vector(const vector& v)
    88. : _start(nullptr)
    89. , _finish(nullptr)
    90. , _endofstorage(nullptr)
    91. {
    92. vector tmp(v.begin(), v.end());
    93. swap(tmp); //this->swap(tmp);
    94. }
    95. //赋值重载函数(现代写法)
    96. vector& operator=(vector v)
    97. {
    98. swap(v); //this->swap(v);
    99. return *this;
    100. }
    101. //析构函数(资源管理)
    102. ~vector()
    103. {
    104. if (_start)
    105. {
    106. delete[] _start;
    107. _start = _finish = _endofstorage = nullptr;
    108. }
    109. }
    110. iterator begin()
    111. {
    112. return _start;
    113. }
    114. iterator end()
    115. {
    116. return _finish;
    117. }
    118. const_iterator begin() const
    119. {
    120. return _start;
    121. }
    122. const_iterator end() const
    123. {
    124. return _finish;
    125. }
    126. size_t size() const
    127. {
    128. return _finish - _start;
    129. }
    130. size_t capacity() const
    131. {
    132. return _endofstorage - _start;
    133. }
    134. void reserve(size_t n)
    135. {
    136. size_t sz = size();
    137. if (n > capacity())
    138. {
    139. T* tmp = new T[n];
    140. if (_start)
    141. {
    142. //memcpy(tmp, _start, size() * sizeof(T)); //浅拷贝问题
    143. for (size_t i = 0; i < size(); ++i)
    144. {
    145. tmp[i] = _start[i];
    146. }
    147. delete[] _start;
    148. }
    149. _start = tmp;
    150. }
    151. _finish = _start + sz;
    152. _endofstorage = _start + n;
    153. }
    154. //总结:vector中,当T涉及深拷贝的类型时,如:string、vector等等,
    155. //扩容使用memcpy拷贝数据会存在浅拷贝问题,造成析构两次
    156. //解决:使用传值拷贝,如上
    157. void push_back(const T& x)
    158. {
    159. /*if (_finish == _endofstorage)
    160. {
    161. size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
    162. reserve(newCapacity);
    163. }
    164. *_finish = x;
    165. ++_finish;*/
    166. //附用insert
    167. insert(end(), x);
    168. }
    169. void pop_back()
    170. {
    171. /*if (_finish > _start)
    172. {
    173. --_finish;
    174. }*/
    175. //附用erase
    176. erase(end() - 1);
    177. }
    178. T& operator[](size_t pos)
    179. {
    180. assert(pos < size());
    181. return _start[pos];
    182. }
    183. const T& operator[](size_t pos) const
    184. {
    185. assert(pos < size());
    186. return _start[pos];
    187. }
    188. //写在类里的小函数,被当做内联函数处理,减少了多次调用建立栈帧
    189. //void resize(size_t n, const T& val = T())
    190. void resize(size_t n, T val = T()) //T()匿名对象,调用默认构造函数,若T()为int(内置类型),
    191. { //C++对于内置类型也可以认为有构造函数、析构函数,才能支持模板,只是int为0,double为0.1
    192. /*int i = 0;
    193. int j = int();
    194. int k = int(1);*/
    195. if (n > capacity())
    196. {
    197. reserve(n);
    198. }
    199. if (n > size())
    200. {
    201. while (_finish < _start + n)
    202. {
    203. *_finish = val;
    204. ++_finish;
    205. }
    206. }
    207. else
    208. {
    209. _finish = _start + n;
    210. }
    211. }
    212. iterator insert(iterator pos, const T& x) //返回值为iterator,解决迭代器失效问题
    213. {
    214. //如果pos传引用,但有些时候,传不过去
    215. //检查参数
    216. assert(pos >= _start && pos <= _finish);
    217. //扩容
    218. //扩容以后,pos就失效了,要更新
    219. //insert导致的迭代器失效,是因为pos没更新
    220. if (_finish == _endofstorage)
    221. {
    222. size_t n = pos - _start;
    223. size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
    224. reserve(newCapacity);
    225. pos = _start + n;
    226. }
    227. //挪动数据
    228. iterator end = _finish - 1;
    229. while (end >= pos)
    230. {
    231. *(end + 1) = *end;
    232. --end;
    233. }
    234. *pos = x;
    235. ++_finish;
    236. return pos;
    237. }
    238. //总结:迭代器在insert里的两种失效:
    239. //1.pos失效 2.迭代器it失效
    240. iterator erase(iterator pos)
    241. {
    242. assert(pos >= _start && pos <= _finish);
    243. iterator it = pos + 1;
    244. while (it != _finish)
    245. {
    246. *(it - 1) = *it;
    247. ++it;
    248. }
    249. --_finish;
    250. return pos;
    251. }
    252. //总结:
    253. //1.erase的失效都是意义变了,过着不在有效访问数据有效范围
    254. //2.一般不会使用缩容的方案,那么erase的失效也不存在野指针的失效
    255. //在VS和Linux不同环境下,处理不同
    256. //erase(pos),使得pos失效,pos的意义改变,但是不同环境平台的处理不一样
    257. //在使用的时候,统一以失效的角度看待
    258. //整体总结:
    259. //对于insert和erase造成的迭代器失效问题,Linux环境下g++检查不严格,基本依靠操作系统自身野指针越界检查机制
    260. //Windows环境下,VS系列检查严格,使用一些强制检查机制,意义改变造成的失效,也可能会检查出来
    261. //vector迭代器的失效有两种:
    262. //1.扩容、缩容,导致形成野指针失效
    263. //2.迭代器指向的位置意义改变
    264. //这些通过操作系统的越界检查机制不一定能检查到
    265. //而通过编译器实现机制检查,相对靠谱
    266. void clear()
    267. {
    268. _finish = _start;
    269. }
    270. private:
    271. iterator _start;
    272. iterator _finish;
    273. iterator _endofstorage;
    274. };
    275. }
    276. 只传迭代器(vector只传迭代器,需要萃取或者将T*封装,这里未实现)
    277. //#pragma once
    278. 模拟实现vector
    279. //#include
    280. //#include
    281. //#include
    282. //#include
    283. //#include"ReverseIterator.h"
    284. //using namespace std;
    285. //
    286. 自定义命名空间,防止与库里的冲突
    287. //namespace my
    288. //{
    289. // template
    290. // class vector
    291. // {
    292. // public:
    293. // typedef T* iterator;
    294. // typedef const T* const_iterator;
    295. // //反向迭代器适配支持
    296. // typedef Reverse_iteratorreverse_iterator;
    297. // typedef Reverse_iteratorconst_reverse_iterator;
    298. //
    299. // 只传迭代器需要支持萃取或者将T*封装
    300. // //typedef Reverse_iteratorreverse_iterator;
    301. // //typedef Reverse_iteratorconst_reverse_iterator;
    302. //
    303. // reverse_iterator rbegin()
    304. // {
    305. // return reverse_iterator(end());
    306. // }
    307. // reverse_iterator rend()
    308. // {
    309. // return reverse_iterator(begin());
    310. // }
    311. // const_reverse_iterator rbegin() const
    312. // {
    313. // return const_reverse_iterator(end());
    314. // }
    315. // const_reverse_iterator rend() const
    316. // {
    317. // return const_reverse_iterator(begin());
    318. // }
    319. //
    320. // //构造函数
    321. // vector()
    322. // :_start(nullptr)
    323. // , _finish(nullptr)
    324. // , _endofstorage(nullptr)
    325. // {}
    326. // //使用n个val构造函数
    327. // vector(size_t n, const T& val = T())
    328. // :_start(nullptr)
    329. // , _finish(nullptr)
    330. // , _endofstorage(nullptr)
    331. // {
    332. // reserve(n);
    333. // for (size_t i = 0; i < n; ++i)
    334. // {
    335. // push_back(val);
    336. // }
    337. // }
    338. // vector(int n, const T& val = T())
    339. // :_start(nullptr)
    340. // , _finish(nullptr)
    341. // , _endofstorage(nullptr)
    342. // {
    343. // reserve(n);
    344. // for (size_t i = 0; i < n; ++i)
    345. // {
    346. // push_back(val);
    347. // }
    348. // }
    349. // //类模板,类构造
    350. // template
    351. // vector(InputIterator first, InputIterator last)
    352. // : _start(nullptr)
    353. // , _finish(nullptr)
    354. // , _endofstorage(nullptr)
    355. // {
    356. // while (first != last)
    357. // {
    358. // push_back(*first);
    359. // ++first;
    360. // }
    361. // }
    362. // void swap(vector& v)
    363. // {
    364. // std::swap(_start, v._start);
    365. // std::swap(_finish, v._finish);
    366. // std::swap(_endofstorage, v._endofstorage);
    367. //
    368. // }
    369. // //拷贝构造函数(使用现代写法)
    370. // vector(const vector& v)
    371. // : _start(nullptr)
    372. // , _finish(nullptr)
    373. // , _endofstorage(nullptr)
    374. // {
    375. // vector tmp(v.begin(), v.end());
    376. // swap(tmp); //this->swap(tmp);
    377. // }
    378. // //赋值重载函数(现代写法)
    379. // vector& operator=(vector v)
    380. // {
    381. // swap(v); //this->swap(v);
    382. // return *this;
    383. // }
    384. // //析构函数(资源管理)
    385. // ~vector()
    386. // {
    387. // if (_start)
    388. // {
    389. // delete[] _start;
    390. // _start = _finish = _endofstorage = nullptr;
    391. // }
    392. // }
    393. //
    394. // iterator begin()
    395. // {
    396. // return _start;
    397. // }
    398. // iterator end()
    399. // {
    400. // return _finish;
    401. // }
    402. // const_iterator begin() const
    403. // {
    404. // return _start;
    405. // }
    406. // const_iterator end() const
    407. // {
    408. // return _finish;
    409. // }
    410. // size_t size() const
    411. // {
    412. // return _finish - _start;
    413. // }
    414. // size_t capacity() const
    415. // {
    416. // return _endofstorage - _start;
    417. // }
    418. // void reserve(size_t n)
    419. // {
    420. // size_t sz = size();
    421. // if (n > capacity())
    422. // {
    423. // T* tmp = new T[n];
    424. // if (_start)
    425. // {
    426. // //memcpy(tmp, _start, size() * sizeof(T)); //浅拷贝问题
    427. // for (size_t i = 0; i < size(); ++i)
    428. // {
    429. // tmp[i] = _start[i];
    430. // }
    431. // delete[] _start;
    432. // }
    433. // _start = tmp;
    434. // }
    435. // _finish = _start + sz;
    436. // _endofstorage = _start + n;
    437. // }
    438. // //总结:vector中,当T涉及深拷贝的类型时,如:string、vector等等,
    439. // //扩容使用memcpy拷贝数据会存在浅拷贝问题,造成析构两次
    440. // //解决:使用传值拷贝,如上
    441. // void push_back(const T& x)
    442. // {
    443. // /*if (_finish == _endofstorage)
    444. // {
    445. // size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
    446. // reserve(newCapacity);
    447. // }
    448. // *_finish = x;
    449. // ++_finish;*/
    450. //
    451. // //附用insert
    452. // insert(end(), x);
    453. // }
    454. // void pop_back()
    455. // {
    456. // /*if (_finish > _start)
    457. // {
    458. // --_finish;
    459. // }*/
    460. //
    461. // //附用erase
    462. // erase(end() - 1);
    463. // }
    464. // T& operator[](size_t pos)
    465. // {
    466. // assert(pos < size());
    467. // return _start[pos];
    468. // }
    469. // const T& operator[](size_t pos) const
    470. // {
    471. // assert(pos < size());
    472. // return _start[pos];
    473. // }
    474. // //写在类里的小函数,被当做内联函数处理,减少了多次调用建立栈帧
    475. // //void resize(size_t n, const T& val = T())
    476. // void resize(size_t n, T val = T()) //T()匿名对象,调用默认构造函数,若T()为int(内置类型),
    477. // { //C++对于内置类型也可以认为有构造函数、析构函数,才能支持模板,只是int为0,double为0.1
    478. // /*int i = 0;
    479. // int j = int();
    480. // int k = int(1);*/
    481. //
    482. // if (n > capacity())
    483. // {
    484. // reserve(n);
    485. // }
    486. // if (n > size())
    487. // {
    488. // while (_finish < _start + n)
    489. // {
    490. // *_finish = val;
    491. // ++_finish;
    492. // }
    493. // }
    494. // else
    495. // {
    496. // _finish = _start + n;
    497. // }
    498. // }
    499. // iterator insert(iterator pos, const T& x) //返回值为iterator,解决迭代器失效问题
    500. // {
    501. // //如果pos传引用,但有些时候,传不过去
    502. // //检查参数
    503. // assert(pos >= _start && pos <= _finish);
    504. // //扩容
    505. // //扩容以后,pos就失效了,要更新
    506. // //insert导致的迭代器失效,是因为pos没更新
    507. // if (_finish == _endofstorage)
    508. // {
    509. // size_t n = pos - _start;
    510. // size_t newCapacity = capacity() == 0 ? 4 : capacity() * 2;
    511. // reserve(newCapacity);
    512. // pos = _start + n;
    513. // }
    514. // //挪动数据
    515. // iterator end = _finish - 1;
    516. // while (end >= pos)
    517. // {
    518. // *(end + 1) = *end;
    519. // --end;
    520. // }
    521. // *pos = x;
    522. // ++_finish;
    523. // return pos;
    524. // }
    525. // //总结:迭代器在insert里的两种失效:
    526. // //1.pos失效 2.迭代器it失效
    527. //
    528. // iterator erase(iterator pos)
    529. // {
    530. // assert(pos >= _start && pos <= _finish);
    531. // iterator it = pos + 1;
    532. // while (it != _finish)
    533. // {
    534. // *(it - 1) = *it;
    535. // ++it;
    536. // }
    537. // --_finish;
    538. // return pos;
    539. // }
    540. // //总结:
    541. // //1.erase的失效都是意义变了,过着不在有效访问数据有效范围
    542. // //2.一般不会使用缩容的方案,那么erase的失效也不存在野指针的失效
    543. // //在VS和Linux不同环境下,处理不同
    544. // //erase(pos),使得pos失效,pos的意义改变,但是不同环境平台的处理不一样
    545. // //在使用的时候,统一以失效的角度看待
    546. //
    547. // //整体总结:
    548. // //对于insert和erase造成的迭代器失效问题,Linux环境下g++检查不严格,基本依靠操作系统自身野指针越界检查机制
    549. // //Windows环境下,VS系列检查严格,使用一些强制检查机制,意义改变造成的失效,也可能会检查出来
    550. //
    551. // //vector迭代器的失效有两种:
    552. // //1.扩容、缩容,导致形成野指针失效
    553. // //2.迭代器指向的位置意义改变
    554. // //这些通过操作系统的越界检查机制不一定能检查到
    555. // //而通过编译器实现机制检查,相对靠谱
    556. // void clear()
    557. // {
    558. // _finish = _start;
    559. // }
    560. //
    561. // private:
    562. // iterator _start;
    563. // iterator _finish;
    564. // iterator _endofstorage;
    565. //
    566. // };
    567. //}

     4.4 test.cpp:

    1. #include"listplus.h"
    2. #include"vectorplus.h"
    3. #include
    4. void test_list_r_iterator()
    5. {
    6. my::list<int> lt;
    7. lt.push_back(10);
    8. lt.push_back(20);
    9. lt.push_back(30);
    10. lt.push_back(40);
    11. lt.push_back(50);
    12. for (auto e : lt)
    13. {
    14. cout << e << " ";
    15. }
    16. cout << endl;
    17. my::list<int>::reverse_iterator rit = lt.rbegin();
    18. while (rit != lt.rend())
    19. {
    20. cout << *rit << " ";
    21. ++rit;
    22. }
    23. cout << endl;
    24. }
    25. void test_vector_r_iterator()
    26. {
    27. my::vector<int> v;
    28. v.push_back(1);
    29. v.push_back(2);
    30. v.push_back(3);
    31. v.push_back(4);
    32. v.push_back(5);
    33. for (auto e : v)
    34. {
    35. cout << e << " ";
    36. }
    37. cout << endl;
    38. my::vector<int>::reverse_iterator rit = v.rbegin();
    39. while (rit != v.rend())
    40. {
    41. cout << *rit << " ";
    42. ++rit;
    43. }
    44. cout << endl;
    45. }
    46. template<class T>
    47. void print_list(const my::list& lt)
    48. {
    49. typename my::list::const_iterator cit = lt.begin(); //auto cit = lt.begin(); //或直接使用auto
    50. while (cit != lt.end())
    51. {
    52. cout << *cit << " ";
    53. ++cit;
    54. }
    55. cout << endl;
    56. }
    57. template<class Container>
    58. void print_Container(const Container& lt)
    59. {
    60. typename Container::const_iterator cit = lt.begin(); //auto cit = lt.begin(); //或直接使用auto
    61. while (cit != lt.end())
    62. {
    63. cout << *cit << " ";
    64. ++cit;
    65. }
    66. cout << endl;
    67. }
    68. int main()
    69. {
    70. //test_list_r_iterator();
    71. //test_vector_r_iterator();
    72. my::list<int> lt1;
    73. lt1.push_back(1);
    74. lt1.push_back(2);
    75. lt1.push_back(3);
    76. lt1.push_back(4);
    77. print_list(lt1);
    78. print_Container(lt1);
    79. my::list lt2;
    80. lt2.push_back("hello");
    81. lt2.push_back("world");
    82. print_list(lt2);
    83. print_Container(lt2);
    84. return 0;
    85. }

     

    后记:
    ●由于作者水平有限,文章难免存在谬误之处,敬请读者斧正,俚语成篇,恳望指教!
                                                                     ——By 作者:新晓·故知

     

  • 相关阅读:
    深入理解JNINativeInterface函数<三>
    二硫化钨/二硒化钨纳米复合材料|WSe2二硒化钨负载掺氮三维石墨烯|氮掺杂二氧化钛负载二硒化钨|二硒化钨薄片/氧化铟纳米线复合材料
    继续总结Python中那些简单好用的用法
    【无标题】积鼎CFD VirtualFlow:航空及汽车燃油晃动流体仿真计算及试验对比
    加速老化测试目的是什么?
    路由、 网络、互联网、因特网、公网私网IP、NAT技术
    Unity之OpenXR+XR Interaction Toolkit快速监听手柄任意按键事件
    linux基础操作代码
    马斯克公开支持上班“摸鱼”,允许员工坐班听音乐,还可外放
    流量回放-The Big Picture
  • 原文地址:https://blog.csdn.net/m0_57859086/article/details/126226346