• 济南网站建设教您:三十分钟掌握STL
  •  

    STL概述
        STL的一个重要特点是数据结构和算法的分离。尽管这是个简单的概念,但这种分离确实使得STL变得非常通用。例如,由于STL的sort()函数是完全通用的,你可以用它来操作几乎任何数据集合,包括链表,容器和数组。
        要点
        STL算法作为模板函数提供。为了和其他组件相区别,在本书中STL算法以后接一对圆括弧的方式表示,例如sort()。
        STL另一个重要特性是它不是面向对象的。为了具有足够通用性,STL主要依赖于模板而不是封装,继承和虚函数(多态性)——OOP的三个要素。你在STL中找不到任何明显的类继承关系。这好像是一种倒退,但这正好是使得STL的组件具有广和ㄓ眯缘牡撞闾卣鳌A硗猓捎赟TL是基于模板,内联函数的使用使得生成的代码短小高效。
        提示
        确保在编译使用了STL的程序中至少要使用-O优化来保证内联扩展。STL提供了大量的模板类和函数,可以在OOP和常规编程中使用。所有的STL的大约50个算法都是完全通用的,而且不依赖于任何特定的数据类型。下面的小节说明了三个基本的STL组件:
        1)           迭代器提供了访问容器中对象的方法。例如,可以使用一对迭代器指定list或vector中的一定范围的对象。迭代器就如同一个指针。事实上,C++的指针也是一种迭代器。但是,迭代器也可以是那些定义了operator*()以及其他类似于指针的操作符地方法的类对象。
        2)           容器是一种数据结构,如list,vector,和deques ,以模板类的方法提供。为了访问容器中的数据,可以使用由容器类输出的迭代器。
        3)           算法是用来操作容器中的数据的模板函数。例如,STL用sort()来对一个vector中的数据进行排序,用find()来搜索一个list中的对象。函数本身与他们操作的数据的结构和类型无关,因此他们可以在从简单数组到高度复杂容器的任何数据结构上使用。
        头文件
        为了避免和其他头文件冲突, STL的头文件不再使用常规的.h扩展。为了包含标准的string类,迭代器和算法,用下面的指示符:
        #include <string>
        #include <iterator>
        #include <algorithm>
        如果你查看STL的头文件,你可以看到象iterator.h和stl_iterator.h这样的头文件。由于这些名字在各种STL实现之间都可能不同,你应该避免使用这些名字来引用这些头文件。为了确保可移植性,使用相应的没有.h后缀的文件名。表1列出了最常使用的各种容器类的头文件。该表并不完整,对于其他头文件,我将在本章和后面的两章中介绍。
        表 1. STL头文件和容器类
        #include
         Container Class
        <deque>
         deque
        <list>
         list
        <map>
         map, multimap
        <queue>
         queue, priority_queue
        <set>
         set, multiset
        <stack>
         stack
        <vector>
         vector, vector<bool>
     
        名字空间
        你的编译器可能不能识别名字空间。名字空间就好像一个信封,将标志符封装在另一个名字中。标志符只在名字空间中存在,因而避免了和其他标志符冲突。例如,可能有其他库和程序模块定义了sort()函数,为了避免和STL地sort()算法冲突,STL的sort()以及其他标志符都封装在名字空间std中。STL的sort()算法编译为std::sort(),从而避免了名字冲突。
        尽管你的编译器可能没有实现名字空间,你仍然可以使用他们。为了使用STL,可以将下面的指示符插入到你的源代码文件中,典型地是在所有的#include指示符的后面:
        using namespace std;
        迭代器
        迭代器提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围。迭代器就如同一个指针。事实上,C++的指针也是一种迭代器。但是,迭代器不仅仅是指针,因此你不能认为他们一定具有地址值。例如,一个数组索引,也可以认为是一种迭代器。
        迭代器有各种不同的创建方法。程序可能把迭代器作为一个变量创建。一个STL容器类可能为了使用一个特定类型的数据而创建一个迭代器。作为指针,必须能够使用*操作符类获取数据。你还可以使用其他数学操作符如++。典型的,++操作符用来递增迭代器,以访问容器中的下一个对象。如果迭代器到达了容器中的最后一个元素的后面,则迭代器变成past-the-end值。使用一个past-the-end值得指针来访问对象是非法的,就好像使用NULL或为初始化的指针一样。
        提示
        STL不保证可以从另一个迭代器来抵达一个迭代器。例如,当对一个集合中的对象排序时,如果你在不同的结构中指定了两个迭代器,第二个迭代器无法从第一个迭代器抵达,此时程序注定要失败。这是STL灵活性的一个代价。STL不保证检测毫无道理的错误。
        迭代器的类型
        对于STL数据结构和算法,你可以使用五种迭代器。下面简要说明了这五种类型:
        ·        Input iterators 提供对数据的只读访问。
        ·        Output iterators 提供对数据的只写访问
        ·        Forward iterators 提供读写操作,并能向前推进迭代器。
        ·        Bidirectional iterators提供读写操作,并能向前和向后操作。
        ·        Random access iterators提供读写操作,并能在数据中随机移动。
        尽管各种不同的STL实现细节方面有所不同,还是可以将上面的迭代器想象为一种类继承关系。从这个意义上说,下面的迭代器继承自上面的迭代器。由于这种继承关系,你可以将一个Forward迭代器作为一个output或input迭代器使用。同样,如果一个算法要求是一个bidirectional 迭代器,那么只能使用该种类型和随机访问迭代器。
        指针迭代器
        正如下面的小程序显示的,一个指针也是一种迭代器。该程序同样显示了STL的一个主要特性——它不只是能够用于它自己的类类型,而且也能用于任何C或C++类型。Listing 1, iterdemo.cpp, 显示了如何把指针作为迭代器用于STL的find()算法来搜索普通的数组。
        表 1. iterdemo.cpp
        #include <iostream.h>
        #include <algorithm>
        using namespace std;
        #define SIZE 100
        int iarray[SIZE];
        int main()
        {
          iarray[20] = 50;
          int* ip = find(iarray, iarray + SIZE, 50);
          if (ip == iarray + SIZE)
            cout << "50 not found in array" << endl;
          else
            cout << *ip << " found in array" << endl;
          return 0;
        }
    在引用了I/O流库和STL算法头文件(注意没有.h后缀),该程序告诉编译器使用std名字空间。使用std名字空间的这行是可选的,因为可以删除该行对于这么一个小程序来说不会导致名字冲突。
     
        程序中定义了尺寸为SIZE的全局数组。由于是全局变量,所以运行时数组自动初始化为零。下面的语句将在索引20位置处地元素设置为50,并使用find()算法来搜索值50:
        iarray[20] = 50;
        int* ip = find(iarray, iarray + SIZE, 50);
        find()函数接受三个参数。头两个定义了搜索的范围。由于C和C++数组等同于指针,表达式iarray指向数组的第一个元素。而第二个参数iarray + SIZE等同于past-the-end 值,也就是数组中最后一个元素的后面位置。第三个参数是待定位的值,也就是50。find()函数返回和前两个参数相同类型的迭代器,这儿是一个指向整数的指针ip。
        提示
        必须记住STL使用模板。因此,STL函数自动根据它们使用的数据类型来构造。
        为了判断find()是否成功,例子中测试ip和 past-the-end 值是否相等:
        if (ip == iarray + SIZE) ...
        如果表达式为真,则表示在搜索的范围内没有指定的值。否则就是指向一个合法对象的指针,这时可以用下面的语句显示::
        cout << *ip << " found in array" << endl;
        测试函数返回值和NULL是否相等是不正确的。不要象下面这样使用:
        int* ip = find(iarray, iarray + SIZE, 50);
添加时间:2013-11-08 点击次数:34

麦谷公益   |   律师声明   |   商务合作   |   联系我们   |   网站地图   |   网站百科

Copyright © 2003 - 2011 Meganet. All Rights Reserved 鲁ICP备09105359号

艾默生UPS电源 艾默生UPS官网 艾默生空调官网 艾默生空调 艾默生精密空调 精密空调网 山特UPS电源 艾默生UPS电源
癫痫病 北京癫痫医院 北京癫痫病医院 癫痫病能治愈吗 癫痫病可以治愈吗 癫痫病的早期症状 癫痫病的早期症状 癫痫病的最新治疗方法 癫痫病人不能吃什么 癫痫病是怎么引起的 北京肾病医院 肾病医院排名 肾病的早期症状 北京肾病医院哪家好 肾病医院 西安康杰癫痫病医院 癫痫病能治愈吗 癫痫病是怎么引起的 北京癫痫病医院 癫痫病的最新治疗方法