转换为list_C++ STL std::list部分实现

602f102fab26e97dc54d67e9f1b743e2.png

写在前面

(本文是个人笔记,有胡言乱语和少数错漏部分)

这篇笔记图解了STL中std::list的实现,并结合代码分析了其迭代器,结点定义,部分成员函数的实现。

最后,仿造std::list的代码,在Leetcode 146. LRU缓存机制中实现了list的部分功能。

总结list的几个要点:

  • list仅持有一个指针p(即 _M_node),指向哨兵节点。p作为end()的返回值。p->next是头节点,也是begin()的返回值,p->prev是back()的返回值。
  • 当list为空时,p->prev = p->next = p;
  • 哨兵节点的数据域可以充当size使用

好啦,只要记住以上几点,并正确的移动指针,就可以随时随地写出list的代码了。

什么是list

list即环状双向链表,即Circular Double Linked List。

list的继承层次

list定义在stl_list.h 中,它的继承关系如下所示:

list-> _List_base [_List_impl -->_Node_alloc_type]

list继承自_LIst_base,而_List_base内含了一个_List_impl类,而_List_impl继承自_Node_alloc_type。 _Node_alloc_type是allocator<_Tp>经过rebind得到的,详见另一篇文章《STL中的vector》实现。

结点定义

结点也具有继承关系: _List_node --> _List_node_base

它们的定义如下:

//gcc 5.4.0 stl_list.h
   77     struct _List_node_base
   78     {
    
   79       _List_node_base* _M_next;
   80       _List_node_base* _M_prev;
   97     };
   98 

 105  template<typename _Tp>
 106  struct _List_node : public __detail::_List_node_base
 107  {
    
 108  ///< User's data.
 109  _Tp _M_data;
 117  };

注意,这里_M_data的类型是_Tp而不是_Tp *

迭代器定义

  • 总的来说,迭代器是一个_List_node_base型的指针。
  • 令我感到不解的是,为什么不是_List_node<_Tp>型的指针。现在因为_M_node是_List_node_base型的指针,当我们想要访问_M_node->_M_data的时候,我们需要进行强制类型转换 static_cast<_List_node<_Tp>>(_M_node)->_M_data。

注:强制类型转换的本质在于地址其实是没有类型的。我们赋予了它的类型,当我们将指针p从A类型转换成B类型时,不管p是否是B类型的,我们总能够p->data_member

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值