老菜的园子

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

C++学习笔记:Container和Iterator
2010-5-26

为什么需要Container

Container和动态对象创建结合起来,实现对大量、数目未知对象的创建、管理。
通常的用法是:根据需要New一个对象;将对象指针保存到Container中;需要访问对象的时候,从Container中获取对象指针。
另外一种管理对象的方法是静态方式,预先创建大规模的对象数组,数量满足系统的最大需要。这种方法会带来性能方面的问题。大量对象创建时要执行构造函数,性能的开销很大。

如何让Container支持不同类型的对象

方法1:Object-Based Hierachy

所有的类都直接或间接地从唯一的根类派生,所有的对象形成单根层级关系。这种方法被很多语言支持,比如Delphi。

对于C++来说,由于支持多继承,不能保证单根对象层次关系,这种方法存在问题。

 

方法2:Template

将类型参数化,代码与具体的类型无关,实现代码的重用。

对于程序员来说,Template的使用更为简单。

 

Template的一些特点:

  • 由编译器完成具体类型的替换;
  • 定义、声明总是放在头文件中;
  • 参数分为class type和Built-in type,后者是compile-time 常量。

Iterator实现

为Container提供一种遍历访问内部元素的机制。Iterator提供了类似指针的行为,使用者可以像访问数组一样访问Container内部的元素,而不必关心Container内部的实现。
Iterator使得不同Container具备相同的元素访问接口。那么,对元素的处理函数可以保持独立,不依赖与具体的Container。元素的处理函数在STL中被称为算法,可以说Iterator机制是STL中算法的基石。

 

Iterator典型的用法:
vector s;
vector::iterator it;
for (it = s.begin(); it != s.end(); it++) {
    cout << *it << endl;
}

从这段代码,我们可以了解到iterator实现上的一些功能要求:

  • iterator内嵌于Container中;
  • Container的begin(), end() 函数创建iterator对象;
  • iterator要支持运算符=, !=, ++, *;


下面是一个iterator实现的简单例子:

  1. #include <iostream>   
  2. using namespace std;  
  3. template  
  4. class PStack {  
  5.     struct LINK {  
  6.         T* data;  
  7.         LINK* next;  
  8.         LINK(T* v, LINK* lk): data(v), next(lk) {}  
  9.     }* head;  
  10. public:  
  11.     PStack(): head(NULL) {}  
  12.     ~PStack() {  
  13.         while (!head) {  
  14.             delete pop();  
  15.         }  
  16.     }  
  17.       
  18.     void add(T* val) {  
  19.         head = new LINK(val, head);  
  20.     }  
  21.     T* pop() {  
  22.         if (head == NULL) {  
  23.             return NULL;  
  24.         }  
  25.         T* data = head->data;  
  26.         LINK* old = head;  
  27.           
  28.         head = head->next;  
  29.           
  30.         delete old;  
  31.         return data;  
  32.     } 

  33.     class iterator;  
  34.     friend class iterator;  
  35.       
  36.     class iterator {  
  37.         PStack* s;  
  38.         LINK* p;  
  39.     public:  
  40.         iterator(): s(NULL), p(NULL) {}  
  41.         iterator(PStack* v): s(v), p(v->head) {}  
  42.         iterator(PStack* v, bool): s(v), p(NULL) {}  
  43.          
  44.         // copy constructor  
  45.         iterator(const iterator& it) {  
  46.             s = it.s;  
  47.             p = it.p;  
  48.         }  
  49.         // =  
  50.         iterator& operator=(const iterator& it) {  
  51.             s = it.s;  
  52.             p = it.p;  
  53.             return *this;  
  54.         }  
  55.         // !=  
  56.         bool operator!= (const iterator& it) {  
  57.             return (p != it.p);  
  58.         }  
  59.         // ++  
  60.         void operator++(int) {  
  61.             if (p != NULL) {  
  62.                 p = p->next;  
  63.             }  
  64.         }  
  65.         // *  
  66.         T* operator*() {  
  67.             if (p == NULL) {  
  68.                 return NULL;  
  69.             }  
  70.               
  71.             return p->data;  
  72.         }      
  73.           
  74.     };  
  75.     // create an iterator object  
  76.     iterator begin() {  
  77.         return iterator(this);  
  78.     }  
  79.     // create an iterator object  
  80.     iterator end() {  
  81.         return iterator(thistrue);  
  82.     }  
  83. };  
  84.   
  85. int main() {  
  86.     PStack s;  
  87.     PStack::iterator it;  
  88.     s.add(new int(2));  
  89.     s.add(new int(4));  
  90.     s.add(new int(1));  
  91.     s.add(new int(3));  
  92.     for (it = s.begin(); it != s.end(); it++) {  
  93.         cout << *it << ":" << **it << endl;  
  94.     }  
  95.       
  96.     return 0;  
  97. }  


 
posted on 2010-09-14 21:57  weichsel  阅读(4817)  评论(2编辑  收藏  举报