编程便笺:Iterator(一)
Iterator是序列概念的体现,Iterator指向值而不是值本身,因而也就具有两方面的特性,一方面Iterator可以指代值,另一方面具有序列指示特性,可以在序列中移动,指针和数组序号都具有这样的特性。Iterator(迭代器)可以说是std的灵魂所在,也可以这样说,Iterator为std的成功提供了保证。
Iterator为什么会如此重要,因为大部分程序都是图灵完备的,所以可以分析一下图灵机,我们把图灵机分成三个部件:条带、接口部件(包括移动和数据捡取部分)、处理部件。这三个部件中,接口部件对应就是Iterator,它是条带与处理部件的纽带,从中可以看出Iterator的重要性。
看std代码,觉得Iterator带点神奇也比较复杂,其实这也是std整体带给我们的印象。从上面图灵机的分析可以看出,Iterator要体现的意图还是比较明确的,而且拨开各种迷雾,std的实现还是非常简洁的。
这篇文章,先来学学迭代器的写法,然后在后续文章中试着编写树、图形等特殊迭代器。
以下的代码摘录自std vector的iterator,为了看起来清楚,做了一些简化。不是很长,就整个列在上面了。
template<class _Ty> class vector; template<class _Ty> class _Vector_iterator { public: typedef vector<_Ty> _Myvec; typedef _Ty* _Tptr; typedef _Ty value_type; typedef _Vector_iterator<_Ty> _Myt; //typedef _Vector_iterator<_Ty> _Mybase; //原来指向const_iterator,简化了。 typedef _Ty value_type; typedef int difference_type; typedef _Ty* pointer; typedef _Ty& reference; _Vector_iterator() { // construct with null vector pointer } _Vector_iterator(pointer _Ptr):_Myptr(_Ptr) { // construct with pointer _Ptr } reference operator*() const { // return designated object return ((reference)*_Myptr); } pointer operator->() const { // return pointer to class object return (&**this); } _Myt& operator++() { // preincrement ++_Myptr; return (*this); } _Myt operator++(int) { // postincrement _Myt _Tmp = *this; ++*this; return (_Tmp); } _Myt& operator--() { // predecrement --_Myptr; return (*this); } _Myt operator--(int) { // postdecrement _Myt _Tmp = *this; --*this; return (_Tmp); } _Myt& operator+=(difference_type _Off) { // increment by integer _Myptr += _Off; return (*this); } _Myt operator+(difference_type _Off) const { // return this + integer _Myt _Tmp = *this; return (_Tmp += _Off); } _Myt& operator-=(difference_type _Off) { // decrement by integer return (*this += -_Off); } _Myt operator-(difference_type _Off) const { // return this - integer _Myt _Tmp = *this; return (_Tmp -= _Off); } difference_type operator-(const _Mybase& _Right) const { // return difference of iterators return _Myptr - _Right._Myptr; } reference operator[](difference_type _Off) const { // subscript return (*(*this + _Off)); } bool operator==(const _Myt& _Right) const { // test for iterator equality return (_Myptr == _Right._Myptr); } bool operator!=(const _Myt& _Right) const { // test for iterator inequality return (!(*this == _Right)); } bool operator<(const _Myt& _Right) const { // test if this < _Right return (_Myptr < _Right._Myptr); } bool operator>(const _Myt& _Right) const { // test if this > _Right return (_Right < *this); } bool operator<=(const _Myt& _Right) const { // test if this <= _Right return (!(_Right < *this)); } bool operator>=(const _Myt& _Right) const { // test if this >= _Right return (!(*this < _Right)); } _Tptr _Myptr; }; template<class _Ty> _Vector_iterator<_Ty> operator+(typename _Vector_iterator<_Ty>::difference_type _Off, _Vector_iterator<_Ty> _Next) { // add offset to iterator return (_Next += _Off); }
从代码可以看出,其实std还是写得比较简洁。在布局、取名、注释、代码行文等方面着比较鲜明的std风格,取名的简洁以及difference_type这样的名字,可以看得出作者的一些偏好,至少是偏重数学。熟悉这些风格,代码看起来还是比较容易。
从上面的代码可以看出,在这里iterator只是对指针作了包装,当然复杂的迭代器不会这么简单,对于iterator来说,主要是移动和取值操作,也就是 *、 ++、 --这三个操作,另外 -> 操作为复合数据提供方便。
operator * 取值代码如下,可以看出只是对指针直接求值。
reference operator*() const { // return designated object return ((reference)*_Myptr); }
operator ++、 -- 操作有两组,分别对应于前置和后置操作。
operator ++、 -- 的前置操作代码如下,比较简单,只是把对应操作作用到指针。
_Myt& operator++() { // preincrement ++_Myptr; return (*this); } _Myt& operator--() { // predecrement --_Myptr; return (*this); }
operator ++、 -- 的后置操作稍微复杂一些,也有点意思,代码如下。与前项操作不一样,多了一个int的参数,至于依据是什么,说实在我也没搞清楚。后缀操作 复制了一个对象,然后本身做前置操作,然后返回拷贝的对象。从这里可以看出实现后缀操作的一些特性,在这里不是等句子结束,而是在这个操作的后续操作中,如继续引用这个对象,则对这个对象并不是指向原来位置,而已经指向新的位置。
_Myt operator++(int) { // postincrement _Myt _Tmp = *this; ++*this; return (_Tmp); } _Myt operator--(int) { // postdecrement _Myt _Tmp = *this; --*this; return (_Tmp); }
下面再来看看vector的代码,与iterator一样,摘录的代码已经对原来代码做了简化。vector的代码如下,因为较长,就不展开了。
template<class _Ty> class vector { // varying size array of values public: typedef vector<_Ty> _Myt; typedef vector<_Ty> _Mybase; typedef size_t size_type; typedef int _Dift; typedef _Dift difference_type; typedef _Ty* _Tptr; typedef const _Ty* _Ctptr; typedef _Tptr pointer; typedef _Ctptr const_pointer; typedef _Ty & _Reft; typedef _Reft reference; typedef const _Ty & const_reference; typedef _Ty value_type; #define _VEC_ITER_BASE(it) (it)._Myptr typedef _Vector_iterator<_Ty> iterator; vector() //构造函数很多,就全简化了 { // construct empty vector _Buy(0); } ~vector() { // destroy the object _Tidy(); } void reserve(size_type _Count) { // determine new minimum length of allocated storage if (capacity() < _Count) { // not enough room, reallocate pointer _Ptr = allocate(_Count); _Umove(begin(), end(), _Ptr); size_type _Size = size(); if (_Myfirst != 0) { // destroy and deallocate old array deallocate(_Myfirst, _Myend - _Myfirst); } _Myend = _Ptr + _Count; _Mylast = _Ptr + _Size; _Myfirst = _Ptr; } } size_type capacity() const { // return current length of allocated storage return (_Myfirst == 0 ? 0 : _Myend - _Myfirst); } iterator begin() { // return iterator for beginning of mutable sequence return (iterator(_Myfirst)); } iterator end() { // return iterator for end of mutable sequence return (iterator(_Mylast)); } void resize(size_type _Newsize) { // determine new length, padding with _Ty() elements as needed resize(_Newsize, _Ty()); } void resize(size_type _Newsize, _Ty _Val) { // determine new length, padding with _Val elements as needed if (size() < _Newsize) _Insert_n(end(), _Newsize - size(), _Val); else if (_Newsize < size()) erase(begin() + _Newsize, end()); } size_type size() const { // return length of sequence return (_Myfirst == 0 ? 0 : _Mylast - _Myfirst); } size_type max_size() const { // return maximum possible length of sequence return -1; } bool empty() const { // test if sequence is empty return (size() == 0); } const_reference at(size_type _Pos) const { // subscript nonmutable sequence with checking return (*(begin() + _Pos)); } reference at(size_type _Pos) { // subscript mutable sequence with checking return (*(begin() + _Pos)); } const_reference operator[](size_type _Pos) const { // subscript nonmutable sequence return (*(_Myfirst + _Pos)); } reference operator[](size_type _Pos) { // subscript mutable sequence return (*(_Myfirst + _Pos)); } reference front() { // return first element of mutable sequence return (*begin()); } const_reference front() const { // return first element of nonmutable sequence return (*begin()); } reference back() { // return last element of mutable sequence return (*(end() - 1)); } const_reference back() const { // return last element of nonmutable sequence return (*(end() - 1)); } void push_back(const _Ty& _Val) { // insert element at end if (size() < capacity()) _Mylast = _Ufill(_Mylast, 1, _Val); else insert(end(), _Val); } void pop_back() { // erase element at end if (!empty()) { // erase last element _Destroy(_Ptr, _Mylast); --_Mylast; } } iterator insert(iterator _Where, const _Ty& _Val) { // insert _Val at _Where size_type _Off = size() == 0 ? 0 : _Where - begin(); _Insert_n(_Where, (size_type)1, _Val); return (begin() + _Off); } void insert(iterator _Where, size_type _Count, const _Ty& _Val) { // insert _Count * _Val at _Where _Insert_n(_Where, _Count, _Val); } iterator erase(iterator _Where) { // erase element at where _STDEXT unchecked_copy(_VEC_ITER_BASE(_Where) + 1, _Mylast, _VEC_ITER_BASE(_Where)); _Destroy(_Mylast - 1, _Mylast); --_Mylast; return (_Where); } iterator erase(iterator _First, iterator _Last) { // erase [_First, _Last) if (_First != _Last) { // worth doing, copy down over hole pointer _Ptr = _STDEXT unchecked_copy(_VEC_ITER_BASE(_Last), _Mylast, _VEC_ITER_BASE(_First)); _Destroy(_Ptr, _Mylast); _Mylast = _Ptr; } return (_First); } void clear() { // erase all erase(begin(), end()); } protected: bool _Buy(size_type _Capacity) { // allocate array with _Capacity elements _Myfirst = 0, _Mylast = 0, _Myend = 0; if (_Capacity == 0) return (false); else { // nonempty array, allocate storage _Myfirst = allocate(_Capacity); _Mylast = _Myfirst; _Myend = _Myfirst + _Capacity; } return (true); } void _Destroy(pointer _First, pointer _Last) { // destroy [_First, _Last) using allocator } void _Tidy() { // free all storage if (_Myfirst != 0) { // something to free, destroy and deallocate it _Destroy(_Myfirst, _Mylast); deallocate(_Myfirst, _Myend - _Myfirst); } _Myfirst = 0, _Mylast = 0, _Myend = 0; } template<class _Iter> pointer _Ucopy(_Iter _First, _Iter _Last, pointer _Ptr) { // copy initializing [_First, _Last), using allocator return unchecked_uninitialized_copy(_First, _Last, _Ptr); } template<class _Iter> pointer _Umove(_Iter _First, _Iter _Last, pointer _Ptr) { // move initializing [_First, _Last), using allocator return ( unchecked_uninitialized_move(_First, _Last, _Ptr)); } void _Insert_n(iterator _Where, size_type _Count, const _Ty& _Val) { // insert _Count * _Val at _Where _Ty _Tmp = _Val; // in case _Val is in sequence size_type _Capacity = capacity(); if (_Count == 0) ; else if (_Capacity < size() + _Count) { // not enough room, reallocate _Capacity = max_size() - _Capacity / 2 < _Capacity ? 0 : _Capacity + _Capacity / 2; // try to grow by 50% if (_Capacity < size() + _Count) _Capacity = size() + _Count; pointer _Newvec = allocate(_Capacity); pointer _Ptr = _Newvec; _Ptr = _Umove(_Myfirst, _VEC_ITER_BASE(_Where), _Newvec); // copy prefix _Ptr = _Ufill(_Ptr, _Count, _Tmp); // add new stuff _Umove(_VEC_ITER_BASE(_Where), _Mylast, _Ptr); // copy suffix _Count += size(); if (_Myfirst != 0) { // destroy and deallocate old array _Destroy(_Myfirst, _Mylast); deallocate(_Myfirst, _Myend - _Myfirst); } _Myend = _Newvec + _Capacity; _Mylast = _Newvec + _Count; _Myfirst = _Newvec; } else if ((size_type)(_Mylast - _VEC_ITER_BASE(_Where)) < _Count) { // new stuff spills off end _Umove(_VEC_ITER_BASE(_Where), _Mylast, _VEC_ITER_BASE(_Where) + _Count); // copy suffix _Ufill(_Mylast, _Count - (_Mylast - _VEC_ITER_BASE(_Where)), _Tmp); // insert new stuff off end _Mylast += _Count; fill(_VEC_ITER_BASE(_Where), _Mylast - _Count, _Tmp); // insert up to old end } else { // new stuff can all be assigned pointer _Oldend = _Mylast; _Mylast = _Umove(_Oldend - _Count, _Oldend, _Mylast); // copy suffix _Unchecked_move_backward(_VEC_ITER_BASE(_Where), _Oldend - _Count, _Oldend); // copy hole fill(_VEC_ITER_BASE(_Where), _VEC_ITER_BASE(_Where) + _Count, _Tmp); // insert into hole } } pointer _Ufill(pointer _Ptr, size_type _Count, const _Ty &_Val) { // copy initializing _Count * _Val, using allocator unchecked_uninitialized_fill_n(_Ptr, _Count, _Val); return (_Ptr + _Count); } private: //这一段代码,是为了简化添加的 _Tptr allocate(size_t count) { return new _Ty[count]; } void deallocate(_Tptr p,size_t count) { return delete[] p; } void fill(pointer _First, pointer _Last, const _Ty &_Val) { // copy _Val through [_First, _Last) for (; _First != _Last; ++_First)*_First = _Val; } pointer unchecked_uninitialized_move(pointer _First, pointer _Last, pointer _Dest) { // move [_First, _Last) to raw _Dest, using _Al return unchecked_uninitialized_copy(_First, _Last, _Dest); } pointer unchecked_uninitialized_copy(pointer _First, pointer _Last, pointer _Dest) { pointer _Next = _Dest; for (; _First != _Last; ++_Dest, ++_First) *_Dest = *_First; return (_Dest); } void unchecked_uninitialized_fill_n(pointer _Ptr, size_type _Count, const _Ty &_Val) { for(;_Count > 0;_Count--) *_Ptr++ = _Val; } pointer _Unchecked_move_backward(pointer _First, pointer _Last, pointer _Dest) { while (_First != _Last) *--_Dest = *--_Last; return (_Dest); } protected: pointer _Myfirst; // pointer to beginning of array pointer _Mylast; // pointer to current end of sequence pointer _Myend; // pointer to end of array };
vector的主体函数都比较简单,有几个辅助代码稍多一些,为简单起见,把allocator整个简化了,去掉的还有反向iterator。
为了保证vector可以独立运行,把几个allocator和内存移动相关的函数,简化后并进到vector中,具体的实现方式只能説是有用,但不严谨,也不高效。而这方面std其实是着墨很多,并使用了许多技巧。但通过上面的结构,对于了解std的设计还是有帮助的。
现在我们还是把注意力回到iterator,从代码可以看出,vector有三个字段,_Myfirst指向数组的起点,_Mylast指向数组数据的后一位置,vector会根据需要多申请一些空间,_Myend指向整个空间的末尾。_Mylast是数据越界的开始,_Myend是内存越界的开始。
protected: pointer _Myfirst; // pointer to beginning of array pointer _Mylast; // pointer to current end of sequence pointer _Myend; // pointer to end of array
从下面的代码可以看出,iterator构建在_Myfirst和_Mylast上,begin()以_Myfirst构建iterator,end()以_Mylast构建iterator,所以可以分别作为迭代的开始和终止条件。
iterator begin() { // return iterator for beginning of mutable sequence return (iterator(_Myfirst)); } iterator end() { // return iterator for end of mutable sequence return (iterator(_Mylast)); }
关于vector其他的就不多説,只是顺带説一下关于vector的内存扩充。从下面摘录自_Insert_n函数的语句可以看出,每一次按50%的容量内存扩充。
else if (_Capacity < size() + _Count) { // not enough room, reallocate _Capacity = max_size() - _Capacity / 2 < _Capacity ? 0 : _Capacity + _Capacity / 2; // try to grow by 50% if (_Capacity < size() + _Count) _Capacity = size() + _Count; pointer _Newvec = allocate(_Capacity);
下面是整个完整的代码,并加了一小段测试。
#include "stdafx.h" #include "stdio.h" #define _DESTRUCTOR(ty, ptr) (ptr)->~ty() template<class _T1, class _T2> inline void _Construct(_T1 *_Ptr, const _T2& _Val) { // construct object at _Ptr with value _Val void *_Vptr = _Ptr; ::new (_Vptr) _T1(_Val); } template<class _Ty> inline void _Destroy(_Ty *_Ptr) { // destroy object at _Ptr _DESTRUCTOR(_Ty, _Ptr); } template<> inline void _Destroy(char *) { // destroy a char (do nothing) } template<> inline void _Destroy(wchar_t *) { // destroy a wchar_t (do nothing) } template<class _Ty> class vector; template<class _Ty> class _Vector_iterator { public: typedef vector<_Ty> _Myvec; typedef _Ty* _Tptr; typedef _Ty value_type; typedef _Vector_iterator<_Ty> _Myt; //typedef _Vector_iterator<_Ty> _Mybase; //原来指向const_iterator,简化了。 typedef _Ty value_type; typedef int difference_type; typedef _Ty* pointer; typedef _Ty& reference; _Vector_iterator() { // construct with null vector pointer } _Vector_iterator(pointer _Ptr):_Myptr(_Ptr) { // construct with pointer _Ptr } reference operator*() const { // return designated object return ((reference)*_Myptr); } pointer operator->() const { // return pointer to class object return (&**this); } _Myt& operator++() { // preincrement ++_Myptr; return (*this); } _Myt operator++(int) { // postincrement _Myt _Tmp = *this; ++*this; return (_Tmp); } _Myt& operator--() { // predecrement --(*(_Mybase *)this); return (*this); } _Myt operator--(int) { // postdecrement _Myt _Tmp = *this; --*this; return (_Tmp); } _Myt& operator+=(difference_type _Off) { // increment by integer _Myptr += _Off; return (*this); } _Myt operator+(difference_type _Off) const { // return this + integer _Myt _Tmp = *this; return (_Tmp += _Off); } _Myt& operator-=(difference_type _Off) { // decrement by integer return (*this += -_Off); } _Myt operator-(difference_type _Off) const { // return this - integer _Myt _Tmp = *this; return (_Tmp -= _Off); } difference_type operator-(const _Mybase& _Right) const { // return difference of iterators return _Myptr - _Right._Myptr; } reference operator[](difference_type _Off) const { // subscript return (*(*this + _Off)); } bool operator==(const _Myt& _Right) const { // test for iterator equality return (_Myptr == _Right._Myptr); } bool operator!=(const _Myt& _Right) const { // test for iterator inequality return (!(*this == _Right)); } bool operator<(const _Myt& _Right) const { // test if this < _Right return (_Myptr < _Right._Myptr); } bool operator>(const _Myt& _Right) const { // test if this > _Right return (_Right < *this); } bool operator<=(const _Myt& _Right) const { // test if this <= _Right return (!(_Right < *this)); } bool operator>=(const _Myt& _Right) const { // test if this >= _Right return (!(*this < _Right)); } _Tptr _Myptr; }; template<class _Ty> _Vector_iterator<_Ty> operator+(typename _Vector_iterator<_Ty>::difference_type _Off, _Vector_iterator<_Ty> _Next) { // add offset to iterator return (_Next += _Off); } template<class _Ty> class vector { // varying size array of values public: typedef vector<_Ty> _Myt; typedef vector<_Ty> _Mybase; typedef size_t size_type; typedef int _Dift; typedef _Dift difference_type; typedef _Ty* _Tptr; typedef const _Ty* _Ctptr; typedef _Tptr pointer; typedef _Ctptr const_pointer; typedef _Ty & _Reft; typedef _Reft reference; typedef const _Ty & const_reference; typedef _Ty value_type; #define _VEC_ITER_BASE(it) (it)._Myptr typedef _Vector_iterator<_Ty> iterator; vector() //构造函数很多,就全简化了 { // construct empty vector _Buy(0); } ~vector() { // destroy the object _Tidy(); } void reserve(size_type _Count) { // determine new minimum length of allocated storage if (capacity() < _Count) { // not enough room, reallocate pointer _Ptr = allocate(_Count); _Umove(begin(), end(), _Ptr); size_type _Size = size(); if (_Myfirst != 0) { // destroy and deallocate old array deallocate(_Myfirst, _Myend - _Myfirst); } _Myend = _Ptr + _Count; _Mylast = _Ptr + _Size; _Myfirst = _Ptr; } } size_type capacity() const { // return current length of allocated storage return (_Myfirst == 0 ? 0 : _Myend - _Myfirst); } iterator begin() { // return iterator for beginning of mutable sequence return (iterator(_Myfirst)); } iterator end() { // return iterator for end of mutable sequence return (iterator(_Mylast)); } void resize(size_type _Newsize) { // determine new length, padding with _Ty() elements as needed resize(_Newsize, _Ty()); } void resize(size_type _Newsize, _Ty _Val) { // determine new length, padding with _Val elements as needed if (size() < _Newsize) _Insert_n(end(), _Newsize - size(), _Val); else if (_Newsize < size()) erase(begin() + _Newsize, end()); } size_type size() const { // return length of sequence return (_Myfirst == 0 ? 0 : _Mylast - _Myfirst); } size_type max_size() const { // return maximum possible length of sequence return -1; } bool empty() const { // test if sequence is empty return (size() == 0); } const_reference at(size_type _Pos) const { // subscript nonmutable sequence with checking return (*(begin() + _Pos)); } reference at(size_type _Pos) { // subscript mutable sequence with checking return (*(begin() + _Pos)); } const_reference operator[](size_type _Pos) const { // subscript nonmutable sequence return (*(_Myfirst + _Pos)); } reference operator[](size_type _Pos) { // subscript mutable sequence return (*(_Myfirst + _Pos)); } reference front() { // return first element of mutable sequence return (*begin()); } const_reference front() const { // return first element of nonmutable sequence return (*begin()); } reference back() { // return last element of mutable sequence return (*(end() - 1)); } const_reference back() const { // return last element of nonmutable sequence return (*(end() - 1)); } void push_back(const _Ty& _Val) { // insert element at end if (size() < capacity()) _Mylast = _Ufill(_Mylast, 1, _Val); else insert(end(), _Val); } void pop_back() { // erase element at end if (!empty()) { // erase last element _Destroy(_Ptr, _Mylast); --_Mylast; } } iterator insert(iterator _Where, const _Ty& _Val) { // insert _Val at _Where size_type _Off = size() == 0 ? 0 : _Where - begin(); _Insert_n(_Where, (size_type)1, _Val); return (begin() + _Off); } void insert(iterator _Where, size_type _Count, const _Ty& _Val) { // insert _Count * _Val at _Where _Insert_n(_Where, _Count, _Val); } iterator erase(iterator _Where) { // erase element at where _STDEXT unchecked_copy(_VEC_ITER_BASE(_Where) + 1, _Mylast, _VEC_ITER_BASE(_Where)); _Destroy(_Mylast - 1, _Mylast); --_Mylast; return (_Where); } iterator erase(iterator _First, iterator _Last) { // erase [_First, _Last) if (_First != _Last) { // worth doing, copy down over hole pointer _Ptr = _STDEXT unchecked_copy(_VEC_ITER_BASE(_Last), _Mylast, _VEC_ITER_BASE(_First)); _Destroy(_Ptr, _Mylast); _Mylast = _Ptr; } return (_First); } void clear() { // erase all erase(begin(), end()); } protected: bool _Buy(size_type _Capacity) { // allocate array with _Capacity elements _Myfirst = 0, _Mylast = 0, _Myend = 0; if (_Capacity == 0) return (false); else { // nonempty array, allocate storage _Myfirst = allocate(_Capacity); _Mylast = _Myfirst; _Myend = _Myfirst + _Capacity; } return (true); } void _Destroy(pointer _First, pointer _Last) { // destroy [_First, _Last) using allocator } void _Tidy() { // free all storage if (_Myfirst != 0) { // something to free, destroy and deallocate it _Destroy(_Myfirst, _Mylast); deallocate(_Myfirst, _Myend - _Myfirst); } _Myfirst = 0, _Mylast = 0, _Myend = 0; } template<class _Iter> pointer _Ucopy(_Iter _First, _Iter _Last, pointer _Ptr) { // copy initializing [_First, _Last), using allocator return unchecked_uninitialized_copy(_First, _Last, _Ptr); } template<class _Iter> pointer _Umove(_Iter _First, _Iter _Last, pointer _Ptr) { // move initializing [_First, _Last), using allocator return ( unchecked_uninitialized_move(_First, _Last, _Ptr)); } void _Insert_n(iterator _Where, size_type _Count, const _Ty& _Val) { // insert _Count * _Val at _Where _Ty _Tmp = _Val; // in case _Val is in sequence size_type _Capacity = capacity(); if (_Count == 0) ; else if (_Capacity < size() + _Count) { // not enough room, reallocate _Capacity = max_size() - _Capacity / 2 < _Capacity ? 0 : _Capacity + _Capacity / 2; // try to grow by 50% if (_Capacity < size() + _Count) _Capacity = size() + _Count; pointer _Newvec = allocate(_Capacity); pointer _Ptr = _Newvec; _Ptr = _Umove(_Myfirst, _VEC_ITER_BASE(_Where), _Newvec); // copy prefix _Ptr = _Ufill(_Ptr, _Count, _Tmp); // add new stuff _Umove(_VEC_ITER_BASE(_Where), _Mylast, _Ptr); // copy suffix _Count += size(); if (_Myfirst != 0) { // destroy and deallocate old array _Destroy(_Myfirst, _Mylast); deallocate(_Myfirst, _Myend - _Myfirst); } _Myend = _Newvec + _Capacity; _Mylast = _Newvec + _Count; _Myfirst = _Newvec; } else if ((size_type)(_Mylast - _VEC_ITER_BASE(_Where)) < _Count) { // new stuff spills off end _Umove(_VEC_ITER_BASE(_Where), _Mylast, _VEC_ITER_BASE(_Where) + _Count); // copy suffix _Ufill(_Mylast, _Count - (_Mylast - _VEC_ITER_BASE(_Where)), _Tmp); // insert new stuff off end _Mylast += _Count; fill(_VEC_ITER_BASE(_Where), _Mylast - _Count, _Tmp); // insert up to old end } else { // new stuff can all be assigned pointer _Oldend = _Mylast; _Mylast = _Umove(_Oldend - _Count, _Oldend, _Mylast); // copy suffix _Unchecked_move_backward(_VEC_ITER_BASE(_Where), _Oldend - _Count, _Oldend); // copy hole fill(_VEC_ITER_BASE(_Where), _VEC_ITER_BASE(_Where) + _Count, _Tmp); // insert into hole } } pointer _Ufill(pointer _Ptr, size_type _Count, const _Ty &_Val) { // copy initializing _Count * _Val, using allocator unchecked_uninitialized_fill_n(_Ptr, _Count, _Val); return (_Ptr + _Count); } private: //这一段代码,是为了简化添加的 _Tptr allocate(size_t count) { return new _Ty[count]; } void deallocate(_Tptr p,size_t count) { return delete[] p; } void fill(pointer _First, pointer _Last, const _Ty &_Val) { // copy _Val through [_First, _Last) for (; _First != _Last; ++_First)*_First = _Val; } pointer unchecked_uninitialized_move(pointer _First, pointer _Last, pointer _Dest) { // move [_First, _Last) to raw _Dest, using _Al return unchecked_uninitialized_copy(_First, _Last, _Dest); } pointer unchecked_uninitialized_copy(pointer _First, pointer _Last, pointer _Dest) { pointer _Next = _Dest; for (; _First != _Last; ++_Dest, ++_First) *_Dest = *_First; return (_Dest); } void unchecked_uninitialized_fill_n(pointer _Ptr, size_type _Count, const _Ty &_Val) { for(;_Count > 0;_Count--) *_Ptr++ = _Val; } pointer _Unchecked_move_backward(pointer _First, pointer _Last, pointer _Dest) { while (_First != _Last) *--_Dest = *--_Last; return (_Dest); } protected: pointer _Myfirst; // pointer to beginning of array pointer _Mylast; // pointer to current end of sequence pointer _Myend; // pointer to end of array }; int _tmain(int argc, _TCHAR* argv[]) { vector<int> v; v.push_back(1); v.push_back(2); for(int i=0;i<v.size();i++) printf("v%d: %d\r\n",i,v[i]); vector<int>::iterator tr; for( tr = v.begin();tr!=v.end();tr++) printf("v%d: %d\r\n",tr - v.begin(),*tr); getchar(); return 1; }