• 反向迭代器------封装的力量


    目录

    一、list封装中模板参数Ref和Ptr的理解

    二、反向迭代器的实现



    一、list封装中模板参数Ref和Ptr的理解

            对于反向迭代器,是我们在前面STL模拟实现中留下的一个问题。在之前的文章中,我们极大程度上的利用了模板,从而减少了许多的代码,如今我们的反向迭代器也是利用了封装+模板的思想,将正向迭代器包装成为了通用的反向迭代器。

            首先我们来看看之前list模拟实现的代码

    1. namespace hmy
    2. {
    3. template<class T>
    4. struct list_node
    5. {
    6. T _data;
    7. list_node* _next;
    8. list_node* _prev;
    9. list_node(const T& x = T())
    10. :_data(x)
    11. , _next(nullptr)
    12. , _prev(nullptr)
    13. {}
    14. };
    15. // T T& T*
    16. // T cosnt T& const T*
    17. template<class T, class Ref, class Ptr>
    18. struct __list_iterator
    19. {
    20. typedef list_node Node;
    21. typedef __list_iterator self;
    22. Node* _node;
    23. __list_iterator(Node* node)
    24. :_node(node)
    25. {}
    26. self& operator++()
    27. {
    28. _node = _node->_next;
    29. return *this;
    30. }
    31. self& operator--()
    32. {
    33. _node = _node->_prev;
    34. return *this;
    35. }
    36. self operator++(int)
    37. {
    38. self tmp(*this);
    39. _node = _node->_next;
    40. return tmp;
    41. }
    42. self operator--(int)
    43. {
    44. self tmp(*this);
    45. _node = _node->_prev;
    46. return tmp;
    47. }
    48. Ref operator*()
    49. {
    50. return _node->_data;
    51. }
    52. Ptr operator->()
    53. {
    54. return &_node->_data;
    55. }
    56. bool operator!=(const self& s)
    57. {
    58. return _node != s._node;
    59. }
    60. bool operator==(const self& s)
    61. {
    62. return _node == s._node;
    63. }
    64. };
    65. template<class T>
    66. class list
    67. {
    68. typedef list_node Node;
    69. public:
    70. typedef __list_iterator iterator;
    71. typedef __list_iteratorconst T&, const T*> const_iterator;
    72. const_iterator begin() const
    73. {
    74. return const_iterator(_head->_next);
    75. }
    76. const_iterator end() const
    77. {
    78. return const_iterator(_head);
    79. }
    80. //这里是传值返回,是一个临时对象,而临时对象具有常性,在以后的使用中不能--,需要写成-1等
    81. iterator begin()
    82. {
    83. return iterator(_head->_next);
    84. //return _head->_next;
    85. }
    86. iterator end()
    87. {
    88. return iterator(_head);
    89. //return _head;
    90. }
    91. void empty_init()
    92. {
    93. _head = new Node;
    94. _head->_next = _head;
    95. _head->_prev = _head;
    96. _size = 0;
    97. }
    98. list()
    99. {
    100. empty_init();
    101. }
    102. // lt2(lt1)
    103. list(const list& lt)
    104. {
    105. empty_init();
    106. for (auto e : lt)
    107. {
    108. push_back(e);
    109. }
    110. }
    111. // lt3 = lt1
    112. /*list& operator=(const list& lt)
    113. {
    114. if (this != <)
    115. {
    116. clear();
    117. for (auto e : lt)
    118. {
    119. push_back(e);
    120. }
    121. }
    122. return *this;
    123. }*/
    124. void swap(list& lt)
    125. {
    126. std::swap(_head, lt._head);
    127. std::swap(_size, lt._size);
    128. }
    129. // lt3 = lt1
    130. list<int>& operator=(list<int> lt)
    131. {
    132. swap(lt);
    133. return *this;
    134. }
    135. ~list()
    136. {
    137. clear();
    138. delete _head;
    139. _head = nullptr;
    140. }
    141. void clear()
    142. {
    143. iterator it = begin();
    144. while (it != end())
    145. {
    146. it = erase(it);
    147. }
    148. }
    149. void push_back(const T& x)
    150. {
    151. insert(end(), x);
    152. }
    153. void push_front(const T& x)
    154. {
    155. insert(begin(), x);
    156. }
    157. void pop_front()
    158. {
    159. erase(begin());
    160. }
    161. void pop_back()
    162. {
    163. erase(--end());
    164. }
    165. iterator insert(iterator pos, const T& x)
    166. {
    167. Node* cur = pos._node;
    168. Node* newnode = new Node(x);
    169. Node* prev = cur->_prev;
    170. // prev newnode cur
    171. prev->_next = newnode;
    172. newnode->_prev = prev;
    173. newnode->_next = cur;
    174. cur->_prev = newnode;
    175. ++_size;
    176. return iterator(newnode);
    177. }
    178. iterator erase(iterator pos)
    179. {
    180. Node* cur = pos._node;
    181. Node* prev = cur->_prev;
    182. Node* next = cur->_next;
    183. delete cur;
    184. prev->_next = next;
    185. next->_prev = prev;
    186. --_size;
    187. return iterator(next);
    188. }
    189. size_t size()
    190. {
    191. return _size;
    192. }
    193. private:
    194. Node* _head;
    195. size_t _size;
    196. };
    197. }

            之前我们的list模拟实现利用了list_node__list_iterator以及list这三个类互相封装来实现代码,其中list_node是链表的节点结构体;__list_iterator是链表的迭代器的结构体;list是封装他们两个结构体的类,这样就构成了list的框架。其中list_node只需要封装节点的关键信息:数据和前后指针;__list_iterator则只需要封装迭代器的成员和相关函数(例如++和--还有*解引用等)。而他们的融合则产生了化学一般的反应----------各个类各司其职,结构分明的组成了一个更加完善更加方便的类----list。而list只需要做的就是把对外的成员函数写出即可(比如begin/end/构造/插入和删除等),至于其他底层的实现则交给了__list_iterator和list_node。这就是封装的力量!

            关于模板参数Ref和Ptr的补充讲解:

            在实例化对象list1的时候就已经明确了他是const对象还是普通对象,然后在调用成员函数的时候,编译器会根据它的类型来确定是调用const修饰的成员函数还是调用普通函数,不论调用的是const修饰的函数还是普通函数,都会先走迭代器的构造函数这一关,(因为他们都是__list_iterator的特殊形式,所以走的都是同一个构造函数)他们在这里将_node赋值为了传入的node值,但是在这里他们已经确定了Ref和Ptr的区别,const_iterator传入的参数是T/const T&/const T*于是这里的Ref和Ptr就分别是const T&和const T*,所以他们在后续的使用中也会产生截然不同的效果

    二、反向迭代器的实现

    言归正传:

            我们的反向迭代器也用到了封装这一核心思想。他为了代码层面的简略,将正向迭代器封装到其中,然后再利用正向迭代器的成员函数就能够轻而易举的实现反向迭代器了。(同样是使用了Ref和Ptr来区别const反向迭代器和普通迭代器)

            

    于是我们只需要在list这个类中补充关于两个反向迭代器的声明和一些成员函数即可正常使用了

            值得注意的是,反向迭代器中的第一个模板参数竟然是一个正向迭代器!!!这其实被我们称为适配器模式,他会跟着我们传入不同类型的迭代器而产生不一样的适配模式,如果传入的参数是list::iterator那么他适配出来的就是list的反向迭代器等等.......

    下面是测试代码:

  • 相关阅读:
    Mybatis-Plus从入门到入土
    Django和Python版本兼容表
    2020华数杯全国大学生数学建模竞赛B题-基于混合模拟退火算法的三维零件的切割模型与计算(附MATLAB代码)
    SpringCloud Alibaba微服务第7章之Nacos
    研发效能工程实践-利用Superset快速打造大数据BI平台
    Java 面试之数据库篇 (offer 拿来吧你)
    财务人员注意!小心黑客“投毒”
    国产开源优秀新一代MPP数据库StarRocks入门之旅-数仓新利器(上)
    Unity技术手册-UGUI零基础详细教程-Toggle切换
    代碼隨想錄算法訓練營|第四十六天|完全背包、518. 零钱兑换 II、377. 组合总和 Ⅳ。刷题心得(c++)
  • 原文地址:https://blog.csdn.net/2303_79336820/article/details/136131229