C ++ Primer study note _ 48_STL analysis (3): The type of iterator, iterator, common container members, and iterator failure

Source: Internet
Author: User

C ++ Primer study note _ 48_STL analysis (3): The type of iterator, iterator, common container members, and iterator failure

1. iterator

1. The iterator is a generic pointer.

Use the *,->, ++, --, and other operators

(1) A normal pointer can point to an address in the memory.

(2) The iterator can point to a location in the container.

2. Each container class template in STL defines a group of corresponding iterator classes. Using the iterator, Algorithm functions can access the elements at the specified position in the container without worrying about the specific types of elements.

Ii. iterator_category

1. Input iterator (* p, ++)

It can be used to read data from a sequence.

2. Output iterator (* p = 0, ++)

Allow writing data to a sequence

3. Forward iterator (++, but not --)

It is both an input iterator and an output iterator, and can traverse the sequence in one way.

4. Bidirectional iterator (++, supporting --)

Similar to the forward iterator, but data can be traversed in both directions.

5. Random Access iterator (++, --, supports + = 5, + 3)

It is also a bidirectional iterator, but can jump between any two positions in the sequence

6. operations implemented by different types of iterators:

3. Common container members

Some of the members listed below are common to all containers and some are unique. Note the differences:

Simple Test Program tracking and debugging is as follows:

#include 
 
  #include 
  
   #include 
   
    using namespace std;int main(void){    vector
    
      v;    v.push_back(1);    v.push_back(2);    v.push_back(3);    vector
     
      ::iterator it;    for (it = v.begin(); it != v.end(); ++it)    {        cout << *it << ' ';    }    cout << endl;    vector
      
       ::reverse_iterator ri; for (ri = v.rbegin(); ri != v.rend(); ++ri) { cout << *ri << ' '; } cout << endl; list
       
         l; l.push_back(1); l.push_back(2); l.push_back(3); list
        
         ::iterator it2; for (it2 = l.begin(); it2 != l.end(); ++it2) { cout << *it2 << ' '; } cout << endl; return 0;}
        
       
      
     
    
   
  
 

 

Let's take a look at the vector. : Iterator and vector : Source code of reverse_iterator:

 

Template <class _ Ty, class _ Alloc> class _ Vector_val: public _ CONTAINER_BASE_AUX_ALLOC <_ Alloc> {// base class for vector to hold allocator _ Alvalprotected: _ Vector_val (_ Alloc _ Al = _ Alloc (): _ CONTAINER_BASE_AUX_ALLOC <_ Alloc> (_ Al), _ Alval (_ Al) {// construct allocator from _ Al} typedef typename _ Alloc: template rebind <_ Ty >:: other _ Alty; _ Alty _ Alval; // allocator object for values }; template <class _ Ty, class _ Ax> class vector: public _ Vector_val <_ Ty, _ Ax> {// varying size array of valuespublic :..... typedef _ Vector_val <_ Ty, _ Ax> _ Mybase; typedef typename _ Mybase: _ Alty _ Alloc; // The typedef _ Vector_iterator <_ Ty, _ Alloc> iterator; typedef _ Vector_const_iterator <_ Ty, _ Alloc> const_iterator; // friend class _ Vector_iterator <_ Ty, _ Alloc>; friend class _ member <_ Ty, _ Alloc>; typedef std: reverse_iterator
 
  
Reverse_iterator; typedef std: reverse_iterator
  
   
Const_reverse_iterator ;.......}; template <class _ Ty, class _ Alloc> class _ Vector_iterator: public _ Vector_const_iterator <_ Ty, _ Alloc >{// iterator for mutable vectorpublic: typedef _ Vector_iterator <_ Ty, _ Alloc> _ Myt; typedef _ Vector_const_iterator <_ Ty, _ Alloc> _ Mybase ;.......}; template <class _ Ty, class _ Alloc> class _ Vector_const_iterator: public _ Ranit <_ Ty, typename _ Alloc: difference_type, typename _ Alloc: const_pointer, typename _ Alloc :: const_reference> {// iterator for nonmutable vectorpublic :..... typedef typename _ Alloc: pointer _ Tptr; typedef skip; typedef _ Ty value_type; typedef typename _ Alloc: difference_type; typedef typename _ Alloc: const_pointer pointer; typedef typename _ Alloc: const_reference reference; typedef const value_type _ FARQ * const_pointer; typedef const value_type _ FARQ & const_reference ;.... _ Tptr _ Myptr; // offset of element in vector}; template
   
    
Class allocator: public _ Allocator_base <_ Ty> {// generic allocator for objects of class _ Typublic :...... typedef _ Allocator_base <_ Ty> _ Mybase; typedef typename _ Mybase: value_type; typedef value_type _ FARQ * pointer; typedef value_type _ FARQ & reference ;...}; // template class _ Allocator_basetemplate
    
     
Struct _ Allocator_base {// base class for generic allocators typedef _ Ty value_type;}; template
     
      
Class reverse_iterator: public _ Revranit <_ RanIt, iterator <...> {// wrap iterator to run it backwards ........ typedef reverse_iterator <_ RanIt> _ Myt; typedef _ RanIt iterator_type ;..............}; // template class _ Revranittemplate <class _ RanIt, class _ Base> class _ Revranit: public _ Base {// wrap iterator to run it backwards .... protected: _ RanIt current; // the wrapped iterator };
     
    
   
  
 

Typedef_Vector_iterator <_ Ty, _ Alloc> iterator; we can see that iterator is only a type definition, while _ Vector_iterator is inherited from _ Vector_const_iterator. This class has a member _ Tptr_Myptr; for more information, see _ Tptr. The type is value_type *. Assume that the current container is vector. Then, value_type is int. In fact, iterator has only one int * _ Myptr; member. That is, the general pointer is encapsulated. Obviously, operator *,->, ++, -- and other operators must be overloaded in the iterator class. These operators actually perform operations on the common pointer _ Myptr. Operator:
// iteratorreference operator*() const{    // return designated object    return ((reference) **(_Mybase *)this);}// const_iteratorreference operator*() const{    // return designated object    .....    return (*_Myptr);}

 

This is iterator * here, (_ Mybase *) this is const_iterator *, * (_ Mybase *) this is the const_iterator object, ** (_ Mybase *) this is the operator * () that calls const_iterator, that is, the * _ Myptr is returned, that is, the pointing element. The operator * of iterator returns a reference, this is actually the const_reference defined in the allocator class, that is, const value_type &. Assume that the current container is a vector The return value is const int &, that is, it cannot be assigned as the left value, but it can be used as the right value, such as cout <* it; similarly, the operator ++ of iterator also calls the operator ++ of const_iterator, and also executes the ++ _ Myptr; Operation in the function. The returned result is const_iterator &, the operator ++ of iterator returns iterator &.

 

Typedef std: reverse_iterator Reverse_iterator; let's look at reverse_iterator. It inherits from _ Revranit. This class has a member _ RanItcurrent. That is to say, there is an iterator class member, that is, an iterator class member. From this perspective, reverse_iterator can also be regarded as an adapter, which uses some operations of the iterator class to complete its own functions.

××××××××××××××××××××××××××××××××××××××××××× ××××××××××××××××××××××××××××××××××××××××××× *

The above introduction is vector: iterator. For example, the implementation of list: iterator is similar. The internal member is also a pointer, but it is a pointer to a Node, for example, _ Nodeptr _ Ptr; // pointer to node

××××××××××××××××××××××××××××××××××××××××××× ××××××××××××××××××××××××××××××××××××××××××× *

Iv. Problem of iterator failure (from http://blog.csdn.net/hackbuteer1/article/details/7734382)

Several Failures of the vector iterator:
1. When an element is inserted (push_back), The iterator returned by the end operation is definitely invalid.
2. When an element is inserted (push_back), the return value of capacity is different from that before the element is inserted, and the entire container needs to be reassigned. In this case, the iterator returned by the first and end operations will become invalid.
3. After the delete operation (erase, pop_back) is performed, all the iterators pointing to the delete vertex are invalid. All the iterators pointing to the elements behind the delete vertex are also invalid.


Deque iterator failure: This is the limitation in C ++ Primer:
1. inserting elements in the front or end of the deque container does not invalidate any iterator.
2. Deleting an element at its header or tail will only invalidate the iterator pointing to the deleted element.
3. Any insert or delete operation at any other location of the deque container will invalidate all iterators pointing to the container element.


The list iterator seems to be ineffective in rare cases. Maybe the iterator pointing to the deleted node will become invalid during deletion, but nothing else has been found.
Let's first look at two regulations:
1. Deletion and insertion of the elements of a node-type container (map, list, set) will invalidate the iterator pointing to the element, and the iterators of other elements will not be affected.
2. Deletion and insertion of the vector element will invalidate the iterator pointing to the element and the subsequent element.


When using the insert or erase function of a container to insert or delete elements through the iterator, The iterator may become invalid. Therefore, we recommend that you obtain the iterator returned by insert or erase, in order to re-obtain the new valid iterator for the correct operation:
The Code is as follows:

iter = vec.insert(iter);iter = vec.erase(iter);

Related Article

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.