STL学习(自学手册+源码分析)之List

1.1 List Node类型

GNU 2.9版本设计实现

template <class _Tp>
struct _List_node {
  typedef void* _Void_pointer;
  _Void_pointer _M_next;//后向指针
  _Void_pointer _M_prev;//前向指针
  _Tp _M_data;//数据域
};

注意这里的_Void_pointer指针设计成了void 类型,实际上存在不妥,其他地方还需要强制转换,而在GNU4.9版本已经将改指针设计成了_List_node自己的类型。

1.2 List 具体实现

1.2.1 List主体

实际实现时,list实际被实现成了双向环状链表(但为了前闭后开区间,最后一个元素是虚拟存在的哨兵)

template <class _Tp, class _Alloc = __STL_DEFAULT_ALLOCATOR(_Tp) >
class list : protected _List_base<_Tp, _Alloc> {
  typedef _List_base<_Tp, _Alloc> _Base;
protected:
  typedef void* _Void_pointer;

public:      
  typedef _Tp value_type;
  typedef value_type* pointer;
  typedef const value_type* const_pointer;
  typedef value_type& reference;
  typedef const value_type& const_reference;
  typedef _List_node<_Tp> _Node;//节点类型
  typedef size_t size_type;
  typedef ptrdiff_t difference_type;

  typedef typename _Base::allocator_type allocator_type;
  allocator_type get_allocator() const { return _Base::get_allocator(); }

public:
  typedef _List_iterator<_Tp,_Tp&,_Tp*>             iterator;
  typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
  ....
  };

1.2.2 _List_iterator

template<class _Tp, class _Ref, class _Ptr>
struct _List_iterator {
  typedef _List_iterator<_Tp,_Tp&,_Tp*>  iterator;
  typedef _List_iterator<_Tp,const _Tp&,const _Tp*> const_iterator;
  typedef _List_iterator<_Tp,_Ref,_Ptr> _Self;

  typedef bidirectional_iterator_tag iterator_category;//(1)
  typedef _Tp value_type;//(2)
  typedef _Ptr pointer;//(3)
  typedef _Ref reference;//(4)
  typedef _List_node<_Tp> _Node;
  typedef size_t size_type;
  typedef ptrdiff_t difference_type;//(5) 下文介绍的五种迭代器关联属性

  _Node* _M_node;//前面的Node节点

  _List_iterator(_Node* __x) : _M_node(__x) {}
  _List_iterator() {}
  _List_iterator(const iterator& __x) : _M_node(__x._M_node) {}

  bool operator==(const _Self& __x) const { return _M_node == __x._M_node; }//数据域判等
  bool operator!=(const _Self& __x) const { return _M_node != __x._M_node; }//数据域判等
  reference operator*() const { return (*_M_node)._M_data; }//返回数据域

#ifndef __SGI_STL_NO_ARROW_OPERATOR
  pointer operator->() const { return &(operator*()); }
#endif /* __SGI_STL_NO_ARROW_OPERATOR */

  _Self& operator++() { //前置递增
    _M_node = (_Node*)(_M_node->_M_next);
    return *this;
  }
  _Self operator++(int) { //后置递增 占位符以进行区分前置递增和后置递增
    _Self __tmp = *this;//应该首先保存自己的值
    ++*this;
    return __tmp;
  }
  _Self& operator--() { 
    _M_node = (_Node*)(_M_node->_M_prev);//向前移动指针
    return *this;
  }
  _Self operator--(int) { 
    _Self __tmp = *this;//保存值返回之后再
    --*this;
    return __tmp;
  }
};

1.2.2 迭代器的设计原则和Iterator traits的作用与设计

Iterator需要遵循的原则:
在这里插入图片描述
算法__rotate( )需要知道iterators的三个associated types(和迭代器相关的属性)

iterator_category();
difference_type();
value_type();

这样的提问在C++标准库开发过程中设计出5种,这个例子中出现了3种,另外两种未在C++标准库中被使用过:referencepointer。即如下所示:

  typedef bidirectional_iterator_tag iterator_category;//(1)表示双向迭代
  typedef _Tp value_type;//(2)值类型
  typedef _Ptr pointer;//(3)指针
  typedef _Ref reference;//(4)引用
  typedef ptrdiff_t difference_type;//(5) 距离

Iterator traits:提取迭代器的属性,如果是类的话直接使用作用域运算符::提取。
如果iterator并不是class呢?例如native pointer(被视为一种退化的iterator)这个时候就需要traits。如下图:
在这里插入图片描述
value type为例:
在这里插入图片描述
完整的triaits的实现:在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值