1.容器

容器是特定类型的对象的集合,也就是为了保存一组对象而设计的类。
容器一般提供插入、删除、查找以及访问容器中的所有对象等功能。
用户不必关心容器中的对象是如何保存的。用户只需要使用容器提供的插入操作将对象放入容器,用删除操作将对象从容器中删除。
容器只关心对象之间的关系,不关心对象本身的类型。容器可以存放各种同类型的对象(如存放一组整型对象、实型对象,也可以存放用户自定义类型的对象)。通常来说容器都会被设计成一个类
数组是容器的一种实现,链表也是容器的一种实现。

2.迭代器

当要访问容器中的某一对象时,必须要有一种方式标识该对象。如果用一个数组保存对象,则可用数组的下标标识正在访问的元素,也可以用指向数组元素的指针来表示。当用链表保存对象时,可以用一个指向某一节点的指针来标识链表中的某一个元素。但容器是抽象的,它保存对象的方法对用户是保密的,因而用户无法指导该如何标识容器中的某一对象。
通常为每种容器定义一个相应的表示其中对象位置的类型,称为迭代器。迭代器对象相当于是指向容器中对象的指针。有了迭代器可以进一步隐藏数据的存储方式。
把迭代器看出是一种抽象的指针。迭代器的常用操作和指针类似,包括赋值、比较、移动到下一个对象或上一个对象、取出指向的对象值。
迭代器一般作为相应类的友元类或内嵌类
迭代器类的对象定义:
容器类名::迭代器类名 迭代器对象名;

template <class T>
class seqlist 
{
private:
     int size;            //数组规模
     int current_size;    //容器中对象个数
     T *storage;          //数组的起始地址
     void doubleSpace();  //将数组容量扩大一倍

public:
    seqlist(int s = 10):size(s)
     {
    storage = new T[size]; current_size = 0;
     }
    ~seqlist() {delete [] storage;}
    void push_back(const T &x) //在容器尾部添加对象
     {
       if (size == current_size) 
           doubleSpace();
       storage[current_size++] = x;
     }
    void pop_back( )           //删除容器尾部的对象
      { 
       if (current_size == 0)
          cout<< "这是一个空容器\n"; 
       else 
          cout<<current_size;
       }
   T &operator[](int i) { return storage[i]; }  //下标运算符重载

   class Itr   //内嵌的迭代器类定义 
      {
          T *pos;  //指向容器中的某一对象
       public:
         Itr(T *obj = NULL) {pos = obj;}
         Itr &operator++() { ++pos;  return *this;}  //指向容器中的下一个对象
         T &operator*()     { return *pos;}          //取出迭代器指向的对象的值
         bool operator!=(const Itr &p)               //比较两个迭代器对象是否相同
                  {return pos != p.pos;}

         friend class seqlist<T>;
      };    
Itr begin() {return Itr(storage);}                  //返回指向第一个对象的迭代器
Itr end()  { return Itr(storage + current_size);}   //返回指向最后一个对象的迭代器
void insert(Itr &p, const T &x) ;                   //在迭代器指定的位置上插入对象
void erase(const Itr &p);                           //删除迭代器指定的位置上的对象
};
//函数实现doubleSpace
template <class T>
void seqlist<T>::doubleSpace() 
{ 
  T *tmp = storage;
  size *= 2;
  storage = new T[size];
  for (int i = 0; i < current_size; ++i)
     storage[i] = tmp[i];
  delete [] tmp;
}
//函数实现insert
template <class T>
void seqlist<T>::insert( Itr &p, const T &x) 
{ 
  T *q;
  if(size == current_size)
   {
     int offset = p.pos - storage;                                              
     doubleSpace(); 
     p.pos = storage + offset;
   }
  q = storage + current_size;
  //插入对象p在q之前(q表示容器中最后一个对象位置),需要把插入对象p之后的元素向后移动腾出位置
  while (q > p.pos) { *q = *(q-1); --q;} 
  *p.pos = x;
  ++current_size;      //插入元素后,数组长度+1
}
//函数实现erase
template <class T>
void seqlist<T>::erase(const Itr &p) 
{   
   T *q =p.pos ;
  --current_size;
  while (q < storage + current_size)
         { *q = *(q+1);   ++q;}
}

应用

int main()
{ 
  seqlist<int>  sq(10);   //容器类对象
  seqlist<int>::Itr itr1; //容器内嵌类--迭代器类对象定义

  for (int i = 0; i < 10;  ++i) 
     sq.push_back(2 * i + 1);
  cout << "用下标运算符输出:\n";
  for (i = 0; i < 10;  ++i) 
     cout << sq[i] << '\t';
  cout << "用迭代器输出:\n";
  for (itr1 = sq.begin() ; itr1 != sq.end();  ++itr1) 
     cout << *itr1 << '\t';
// 插入0,2,4,6,8,10,12,14,16,18
for (itr1 = sq.begin(), i = 0 ;  i < 20; 
        ++itr1, ++itr1, i += 2) 
    sq.insert(itr1, i);
cout << "插入0,2,4,6,8,10,12,14,16,18:\n";
for (itr1 = sq.begin() ; itr1 != sq.end();  ++itr1) 
      cout << *itr1 << '\t';
//删除0,2,4,6,8,10,12,14,16,18
for (itr1 = sq.begin(); itr1 != sq.end(); ++itr1) 
       sq.erase(itr1);
cout << "删除0,2,4,6,8,10,12,14,16,18:\n";
for (itr1 = sq.begin() ; itr1 != sq.end();  ++itr1) 
       cout << *itr1 << '\t';

return 0;
}