STL Learning--vector Chapter

Source: Internet
Author: User

STL Learning--vector Chapter
  • About Vector

    Vector data is arranged and operated in a very similar way to array, where the difference lies in the flexibility of space use. array is static space, once configured, it can not be changed ; To change a big (or small) a little bit, but trivial things client completion: First configure a new space, and then the elements from the site one by one moved to the site, and then the original space back to the system. Vector is a dynamic space, with the addition of elements, its internal mechanism will automatically expand space to accommodate the new elements . It is very helpful for the rational use and flexible use of memory.

    Vector implementation of the key technology: the size of the control and reconfiguration of the data movement efficiency , vector expansion space is "To configure new space, moving data, release the old space" process.

  • Vector definition

    Vector definition mainly includes allocating space, defining corresponding internal properties, defining basic methods and so on.

  • Vector iterators

    Vector maintains a continuous space, so regardless of its element type, the normal pointer can be used as the vector iterator, the vector iterator needs to do mainly include: operator *,operator->,operator++, operator–,operator+,operator-,operator+=,operator-= and so on. Vector supports random access, and the normal pointer can achieve this ability. So the random Access iterators is provided in the vector.

  • Vector data structure

    The vector data structure is linear continuous space , there are two iterator start and finish, pointing to the currently used range in the configured continuous space, and the iterator end_of_storage points to the end of the whole contiguous space (including the spare space).

    To reduce the speed cost of space configuration, the actual size of the vector may be larger than the client requirements for future expansion. That is the capacity. The capacity of a vector is always greater than or equal to its size. Once the capacity is equal to the size, it is loaded, and the next time a new element is added, the whole vector needs another space. With Start,finish,end_of_storage three iterators, you can easily provide the first and last signs, size, capacity, empty container judgments, label operators ([]), front-end elements, and finally end elements.

    Vector expansion principle: If it exceeds the current capacity, then the capacity will be expanded to twice times, if twice times the capacity is still insufficient, the expansion to large enough capacity .

  • Structure and memory management of vectors

    The structure and memory management of vectors mainly involve constructor and push_back functions. Its memory allocation mainly uses the Data_allocatir function, it is convenient to configure the space of n elements. Vector has multiple version constructors, one of which allows you to specify a space size and an initial value. The push_back function in the vector inserts the new element into the end of the vector, which first checks to see if there is any spare space, and if so, constructs the element directly on the spare space and adjusts the iterator finish to make the vector larger. If there is no spare space, you need to expand the space (reconfigure, move the data, release the original space).

    Note:vector dynamic Increase in size, not after the original space after the new space (because there is no guarantee of space after the original space), but instead of twice times the original size of another large space, and then copy the original content, and then began to construct new elements after the original content, and release the original space. Therefore, any operation on the vector, once the space is reconfigured, all iterators pointing to the original vector are invalidated .

  • Element manipulation of vectors

    Vector provides more elements, mainly including Push_back,pop_back,erase,clear,insert and so on. Detailed introduction of the following source code analysis.

  • Vector Source Analysis

    Vector class definition Template <class _tp, class _alloc = __stl_default_allocator (_TP) >class vector:protected _vector_base& LT;_TP, _alloc> {///requirements: __stl_class_requires (_TP, _assignable);p rivate:typedef _vector_base<_tp, _All                       Oc> _base;public://vector nested type definition typedef _TP VALUE_TYPE;                  Vector element type typedef value_type* pointer;      Vector pointer typedef const VALUE_TYPE* Const_pointer;                 Vector static pointer typedef value_type* iterator;     Vector iterator is a normal pointer typedef const VALUE_TYPE* CONST_ITERATOR;                Vector iterator static pointer typedef value_type& reference;    Vector referencing typedef const value_type& Const_reference;                     Vector static reference typedef size_t SIZE_TYPE;            Vector size typedef ptrdiff_t DIFFERENCE_TYPE;  Vector type typedef typename _BASE::ALLOCATOR_TYPE Allocator_type;  Allocator_type Get_allocator () const {return _base::get_allocator ();} PROTECTED://is a simple space configurator #ifdEF __stl_has_namespaces using _base::_m_allocate;  Using _base::_m_deallocate;               Using _base::_m_start;              A head using _base::_m_finish that represents the current use of space;      Indicates the trailing using _base::_m_end_of_storage of the currently used space; Indicates the current space available tail #endif/* __stl_has_namespaces */protected://Insert auxiliary function void _m_insert_aux (iterator __position, const _TP&AMP ;  __X);  void _m_insert_aux (iterator __position);p ublic://Vector head node element iterator begin () {return _m_start;}  Const_iterator begin () const {return _m_start;}  Vector tail node element iterator end () {return _m_finish;}  Const_iterator End () const {return _m_finish;}  The head node after vector reversal Reverse_iterator Rbegin () {return reverse_iterator (end ());}  Const_reverse_iterator Rbegin () const {return const_reverse_iterator (end ());}  Tail node after vector reversal Reverse_iterator rend () {return reverse_iterator (begin ());}  Const_reverse_iterator rend () const {return const_reverse_iterator (begin ());} Returns the number of current objects Size_type size () const {return sizE_type (end ()-begin ());  }//Returns the maximum size Size_type max_size () const {return size_type ( -1)/sizeof (_TP);}  Returns the maximum number of objects that can be stored in the reallocation Memory Size_type capacity () const {return size_type (_m_end_of_storage-begin ());}  Determines whether the NULL function bool empty () const {return begin () = = End ();}  Vector value Manipulation reference operator[] (Size_type __n) {return * (begin () + __n);}  Const_reference operator[] (size_type __n) const {return * (begin () + __n);}  Vector constructor, which allows to specify vector size n and initial value explicit vector (const allocator_type& __a = Allocator_type ()): _base (__a) {} Vector (Size_type __n, const _tp& __value, const allocator_type& __a = Allocator_type ()): _base (__n,  __a) {_m_finish = Uninitialized_fill_n (_m_start, __n, __value);} Explicit vector (Size_type __n): _base (__n, Allocator_type ()) {_m_finish = Uninitialized_fill_n (_m_start, __n, _TP ( )); } vector (const VECTOR&LT;_TP, _alloc>& __x): _base (__x.size (), __x.get_allocator ()) {_m_finish = UnInitIalized_copy (__x.begin (), __x.end (), _m_start);         }//For integral type, do not use iterator template <class _inputiterator> vector (_inputiterator __first, _inputiterator __last, Const allocator_type& __a = Allocator_type ()): _base (__a) {typedef typename _IS_INTEGER&LT;_INPUTITERATOR&GT    ;:: _integral _integral;  _m_initialize_aux (__first, __last, _integral ()); } template <class _integer> void _m_initialize_aux (_integer __n, _integer __value, __true_type) {_M_start = _M    _allocate (__n);     _m_end_of_storage = _m_start + __n;  _m_finish = Uninitialized_fill_n (_m_start, __n, __value); }//Vector initialization auxiliary function template <class _inputiterator> void _m_initialize_aux (_inputiterator __first, _inputiterator  __last, __false_type) {_m_range_initialize (__first, __last, __iterator_category (__first));  }vector (const _tp* __first, const _tp* __last, const allocator_type& __a = Allocator_type ()): _base (__last -__first, __a) {_m_fInish = Uninitialized_copy (__first, __last, _m_start);  }//destructor ~vector () {Destroy (_m_start, _m_finish);} ...//Configure space and fill #ifdef __stl_member_templates template <class _forwarditerator> iterator _m_allocate_and_copy (size _type __n, _forwarditerator __first, _forwarditerator __last) {iterator    __result = _m_allocate (__n);      __stl_try {uninitialized_copy (__first, __last, __result);    return __result;  } __stl_unwind (_m_deallocate (__result, __n));                                                } #else/* __stl_member_templates */iterator _m_allocate_and_copy (size_type __n, Const_iterator __first,    Const_iterator __last) {iterator __result = _m_allocate (__n);      __stl_try {uninitialized_copy (__first, __last, __result);    return __result;  } __stl_unwind (_m_deallocate (__result, __n));                 } #endif/* __stl_member_templates */... reference front () {return *begin ();} The first element of Const_referenCE Front () const {return *begin ();}              Reference back () {return * (end ()-1);}  The last element const_reference back () const {return * (end ()-1);} void push_back (const _tp& __x) {//Inserts an element into the end of the value if (_m_finish! = _m_end_of_storage) {//also has spare space con             struct (_m_finish, __x);                           global function ++_m_finish;             Adjust the height of the water level} else//No spare space _m_insert_aux (end (), __x);      The function is a member function of the vector} void Push_back () {if (_m_finish! = _m_end_of_storage) {construct (_m_finish);    ++_m_finish;  } else _m_insert_aux (end ()); } ...//starting from position, insert n elements, element initial value is x void Insert (iterator __pos, size_type __n, const _tp& __x) {_m_fill_insert (__p OS, __n, __x);   } void _m_fill_insert (iterator __pos, size_type __n, const _tp& __x);                          See below analysis//Take off the tail element and resize void Pop_back () {//Remove the tail element--_m_finish;           The trailing end is marked forward with a lattice, indicating that the trailing element destroy (_m_finish) will be discarded; Destroy is the global function}//Clears the element at a location iterator erase (iterator __position) {//Clears the element at a location if (__position + 1!).   = End ()) copy (__position + 1, _m_finish, __position);    The subsequent elements move forward--_m_finish;    Destroy (_m_finish);  return __position; }//Clears all elements in [first,last] iterator erase (iterator __first, iterator __last) {iterator __i = copy (__last, _m_finish, __first);    Copy is the global function destroy (__i, _m_finish);    _m_finish = _m_finish-(__last-__first);  return __first; }//adjust vector size void resize (size_type __new_size, const _tp& __x) {if (__new_size < size ()) Erase (begin    () + __new_size, End ());  else Insert (end (), __new_size-size (), __x);  } void Resize (Size_type __new_size) {Resize (__new_size, _TP ());} Clears the vector element void clear () {Erase (Begin (), end ());} ... template <class _tp, class _alloc>void vector<_tp, _alloc>::_m_insert_aux (iTerator __position, const _tp& __x) {if (_m_finish! = _m_end_of_storage) {//also has spare space constru                   CT (_m_finish, * (_m_finish-1));                                              Constructs an element at the beginning of the alternate space and initializes the ++_m_finish with the last element value of the vector;    Adjust the water level _tp __x_copy = __x;    Copy_backward (__position, _m_finish-2, _m_finish-1);  *__position = __x_copy;    } else {//No spare space const SIZE_TYPE __old_size = size (); Const Size_type __len = __old_size! = 0?    2 * __OLD_SIZE:1; The above configuration principle: If the original size is 0, then configure 1 (element size);//If the original size is not 0, then configure twice times the original size,//The first half is used to place the original data, the second half is ready to be used to place the new data iterator __new_start = _m_alloca                Te (__len);    Actual configuration iterator __new_finish = __new_start;     __stl_try {__new_finish = Uninitialized_copy (_m_start, __position, __new_start);                                             Copy the contents of the original vector to the new vector construct (__new_finish, __x); Set the initial value x ++__new_finish for the new element;                                                          Adjust the water level __new_finish = Uninitialized_copy (__position, _m_fi   Nish, __new_finish); Copy the original contents of the placement site} __stl_unwind (Destroy (__new_start,__new_finish), _m_deallocate (__new_start,__le    n)));                                                    Destroy (Begin (), end ());    Destruction and release of the original Vector _m_deallocate (_m_start, _m_end_of_storage-_m_start);                                                     _m_start = __new_start;    Adjust the iterator, pointing to the new vector _m_finish = __new_finish;  _m_end_of_storage = __new_start + __len; }}//starts with position, inserts n elements, the initial value of the element is Xtemplate <class _TP, Class _alloc>void vector<_tp, _alloc>::_m_fill_insert (                                                       Iterator __position, Size_type __n, const _tp& __x) {if (__n! = 0) { When N!=0 does all of the following actions if (Size_type (_m_end_of_storage-_m_finish) >= __n ) {//spare space greater than or equal to the number of new elements _Tp __x_copy = __x;           Const Size_type __elems_after = _m_finish-__position;                             Calculates the number of existing elements after the insertion point iterator __old_finish = _m_finish; The number of existing elements after the IF (__elems_after > __n) {//insertion point is greater than the number of new elements uninitialized_copy (_m_              Finish-__n, _m_finish, _m_finish);                                               _m_finish + = __n;        Mark the tail end of the vector and move the Copy_backward (__position, __old_finish-__n, __old_finish);                   Fill (__position, __position + __n, __x_copy);                                                                   Start filling new value after insertion point} else {//insertion point after the number of existing elements is less than or equal to the number of new elements Uninitialized_fill_n (_m_finish, __n-__elems_after, __x_co         PY);        _m_finish + = __n-__elems_after;        Uninitialized_copy (__position, __old_finish, _m_finish); _m_finish + = __elems_after      Fill (__position, __old_finish, __x_copy);              }} else {//spare space is less than the number of new elements (additional memory must be configured), first determine the new length: twice times the old length, or the old length + the number of new elements const Size_type __old_size = size ();      Const Size_type __len = __old_size + Max (__old_size, __n);      The following configuration of the new vector space iterator __new_start = _m_allocate (__len);      Iterator __new_finish = __new_start; __stl_try {//below first copies the elements before the insertion point of the old vector to the new space __new_finish = Uninitialized_copy (_m_start, __position, __new_st        ART);        The following will add new elements (the initial value is N) to fill in the space __new_finish = Uninitialized_fill_n (__new_finish, __n, __x);      The following then copies the elements after the insertion point of the old vector into the new space __new_finish = Uninitialized_copy (__position, _m_finish, __new_finish);      } __stl_unwind ((Destroy (__new_start,__new_finish), _m_deallocate (__new_start,__len)));      The following clears and releases the old vector destroy (_m_start, _m_finish);      _m_deallocate (_m_start, _m_end_of_storage-_m_start);  The following adjustment water level mark _m_start = __new_start;        _m_finish = __new_finish;    _m_end_of_storage = __new_start + __len;    }}}//vector reversal function void Reserve (Size_type __n) {if (Capacity () < __n) {Const Size_type __old_size = size ();    Iterator __tmp = _m_allocate_and_copy (__n, _m_start, _m_finish);    Destroy (_m_start, _m_finish);    _m_deallocate (_m_start, _m_end_of_storage-_m_start);    _m_start = __tmp;    _m_finish = __tmp + __old_size;  _m_end_of_storage = _m_start + __n; }}
  • Reference documents

    STL Source Code Analysis--Houtie
    STL Source Code

STL Learning--vector Chapter

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.