zoukankan      html  css  js  c++  java
  • C++学习笔记:Container和Iterator(转)

    原文链接:http://www.cnblogs.com/weichsel/archive/2010/09/14/1826300.html

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

  • 相关阅读:
    让GoogleCode的SVN下的HTML文件在FireFox下正常显示
    添加验证控件出错
    【转载】SQLServer中char、varchar、nchar、nvarchar的区别:
    人生第一篇博客
    二叉排序树
    最小编辑距离
    面试题集锦_4
    面试题集锦_3
    键树
    B树
  • 原文地址:https://www.cnblogs.com/wodehao0808/p/3465737.html
Copyright © 2011-2022 走看看