vector迭代器實現為類指標
class vector : protected _vector_base<_tp, _alloc>
iterator erase(iterator __first, iterator __last)
可以看到如果容量足夠(無需擴容),則操作是將插入位置後的元素整體往後挪動乙個位置,也就是插入位置之後的元素位址都會改變;否則,容量不夠需要重新申請一塊記憶體,然後將元素拷貝過去,這導致所有元素的位址都會改變。
iterator insert(iterator __position, const _tp& __x)
else
_m_insert_aux(__position, __x);
return begin() + __n;
} iterator insert(iterator __position)
else
_m_insert_aux(__position);
//返回插入元素的迭代器
return begin() + __n;
}template void
vector<_tp, _alloc>::_m_insert_aux(iterator __position)
else
__stl_unwind((destroy(__new_start,__new_finish),
_m_deallocate(__new_start,__len)));
//釋放原來的容器元素佔據的記憶體
destroy(begin(), end());
_m_deallocate(_m_start, _m_end_of_storage - _m_start);
_m_start = __new_start;
_m_finish = __new_finish;
_m_end_of_storage = __new_start + __len;
}}
可以看到list迭代器實現為模板類_list_iterator
template class list : protected _list_base<_tp, _alloc>
public:
//迭代器由模板類實現
typedef _list_iterator<_tp,_tp&,_tp*> iterator;
看下_list_iterator的具體實現,可以看到我們得到的迭代器實質是 指向每乙個鍊錶節點_list_node_base的指標
templatestruct _list_iterator : public _list_iterator_base
_list_iterator() {}
_list_iterator(const iterator& __x) : _list_iterator_base(__x._m_node) {}
reference operator*() const
#ifndef __sgi_stl_no_arrow_operator
pointer operator->() const
#endif /* __sgi_stl_no_arrow_operator */
//前置++
_self& operator++()
//後置++
_self operator++(int)
//前置--
_self& operator--()
//後置--
_self operator--(int)
}; void _m_incr()
void _m_decr()
可以看到只有刪除節點的記憶體被釋放了,指向他的指標也就無效了,其他位置元素的位址並無改變
iterator erase(iterator __position)
只是改變了插入位置元素的前繼指標和其前繼元素的後繼指標,各個節點的迭代器(位址並無改變)
iterator insert(iterator __position, const _tp& __x)
可以看到直接被定義為底層資料介面紅黑樹的迭代器:
template class map
public:
bool operator()(const value_type& __x, const value_type& __y) const
};private:
//底層紅黑樹類
typedef _rb_tree, key_compare, _alloc> _rep_type;
_rep_type _m_t; // red-black tree representing map
public:
typedef typename _rep_type::pointer pointer;
typedef typename _rep_type::const_pointer const_pointer;
typedef typename _rep_type::reference reference;
typedef typename _rep_type::const_reference const_reference;
//直接定義為底層資料結構紅黑樹類的迭代器
typedef typename _rep_type::iterator iterator;
typedef typename _rep_type::const_iterator const_iterator;
typedef typename _rep_type::reverse_iterator reverse_iterator;
typedef typename _rep_type::const_reverse_iterator const_reverse_iterator;
typedef typename _rep_type::size_type size_type;
typedef typename _rep_type::difference_type difference_type;
typedef typename _rep_type::allocator_type allocator_type;
然後我們看下紅黑樹類中,關於迭代器的實現:
class _rb_tree : protected _rb_tree_base<_value, _alloc>
_rb_tree_iterator(_link_type __x)
_rb_tree_iterator(const iterator& __it)
reference operator*() const
#ifndef __sgi_stl_no_arrow_operator
pointer operator->() const
#endif /* __sgi_stl_no_arrow_operator */
//前置++
_self& operator++()
//後置++
_self operator++(int)
//前置--
_self& operator--()
//後置--
_self operator--(int)
};
實質是底層紅黑樹執行erase操作
void erase(iterator __position)
size_type erase(const key_type& __x)
void erase(iterator __first, iterator __last)
稍微了解紅黑刪除節點過程的可以知道,刪除過程只會修改刪除節點的相關的左右子樹指標,而不會改變其他節點的位址,所以除了被銷毀的刪除節點外,其他節點的迭代器不會失效。
實質也是底層紅黑樹執行insert操作,所有節點迭代器都不會失效,因為節點本身的位址沒有改變,改變的只是其成員——指向左右子樹的指標的值。
pairinsert(const value_type& __x)
iterator insert(iterator position, const value_type& __x)
#ifdef __stl_member_templates
template void insert(_inputiterator __first, _inputiterator __last)
#else
void insert(const value_type* __first, const value_type* __last)
void insert(const_iterator __first, const_iterator __last)
C STL之迭代器介紹 原理 失效
今天抽空來看看c 標準庫中迭代器的相關知識。我們知道,stl標準庫一共有六大部件 分配器 容器 迭代器 演算法 仿函式 介面卡。其中,迭代器就是用來 聯結 演算法 仿函式與容器的紐帶。除此之外,在設計模式中有一種模式叫迭代器模式,簡單來說就是提供一種方法,在不需要暴露某個容器的內部表現形式情況下,使...
迭代器失效小分析
stl中容器按儲存方式分為兩類 一是按陣列容器順序儲存的序列式容器 如 vector,deque 另一類是以不連續的節點形式儲存的容器 list set map 迭代器失效小例項 void printvector vector v cout endl void testvector 迭代器失效 對於...
STL之迭代器失效
所謂迭代器失效,是指迭代器已經不是指向原來的位置,這總是出現在需要連續儲存的容器中,如 vector,deque,string。拿vector來說,當需要插入或者刪除元素時,如果原來的容量 capacity 不足以滿足插入的需求,則必須重新分配一塊記憶體,然後將vector物件中所有元素都搬新家,這...