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++标准库中被使用过:reference
和pointer
。即如下所示:
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
的实现: