c++ STL之通用编程技术

来源:互联网 发布:字母组成单词软件 编辑:程序博客网 时间:2024/05/16 02:51

 STL是一种通用编程技术。面向对象编程关注的是编程的数据方面,而通用编程技术关注的算法,它们之间的共同点事抽象和创建可重用代码,但他们的理念决然不同。

                通用编程技术旨在编写独立于数据类型的代码。在C++中,完成通用程序的工具是模板。当然,模板使得能够按通用类型定义函数或类,而STL通过通用算法更进了一步。模板让这一切成为可能,但必须对元素进行仔细地设计。为了解模板和设计师如何协同工作的,我们来看看需要迭代器的原因。

           不同的算法对迭代器要求也不同。STL定义了5种迭代器,并根据所需的迭代器类型对算法进行了描述。这5种迭代器分别是输入迭代器,输出迭代器,正向迭代器,双向迭代器和随机访问迭代器。

                 1.输入迭代器

                 术语“输入”是从程序的角度说的,即来自容器的信息被视为输入,就像来自键盘的信息对程序来说是输入一样。因此,输入迭代器可被程序用来读取容器中的信息。

输入迭代器必须能偶访问容器中所有的值,这是通过支持++操作符(前缀格式和后缀格式)来实现的。输入迭代器是单向迭代器,可以递增,但不能倒退。

                 2.输出迭代器

                 STL使用术语“输出”来指用于将信息从程序传输给容器的迭代器,因此程序的输出就是容器的输入。输出迭代器与输入迭代器相似,只是接触引用让程序能够容器值,而不能读取。简而言之,对于单通行,只读算法,可以使用输入迭代器;而对于单通行,只写算法,则可以使用输出迭代器。

                  3.正向迭代器

                  与输入迭代器和输出迭代器相似,正向迭代器只使用++操作符来遍历容器,所以它每次沿容器向前移动一个元素;不过,与输入和输出迭代器不同的是,它总是按相同的顺序遍历一系列值。 

                   4.双向迭代器

                   双向迭代器具有正向迭代器的所有特性,同时支持两种(前缀和后缀)递减操作符。

                   5.随机访问迭代器

                   有些算法(如标准排序和二分检索)要求能够直接跳到容器中的任何一个元素,这叫作随机访问,需要随机访问迭代器。随机访问迭代器具有正向迭代器的所有特性,同时添加了支持随机访问的操作(如指针增加运算)和用于对元素进行排序的关系操作符。

                   STL提供了一些预定义迭代器。

                    copy() ----->可以讲数据从一个容器复制到另一个容器中。也可以在数组之间复制,因为可以将指向数组的指针用作迭代器。

                     例如:

[cpp] view plaincopyprint?
  1. int cats[10] = {1,2,3,4,5,6,7,8,9,10} ;
  2. vector<int> dice(10);  
  3. copy(cats,cats+10,dice.begin());  

                    ostream_iterator  ----->表示输出流的迭代器。用STL的话说,该模板是输出迭代器概念的一个模型,它也是一个适配器---------一个类或函数,可以将一些其他接口转换为STL使用的接口。

使用示例:

[cpp] view plaincopyprint?
  1. include<iterator>  
  2. ....  
  3. ostream_iterator<int,char>out_iter(cout," ");  
说明:

out_iter迭代器现在一个接口,让您能够使用cout来显示信息。第一个模版参数指出了被发送给输出流的数据类型;第二个参数指出了输出流使用的字符类型。

                   与ostream_iterator相似,istream_iterator也使用两个模板参数。第一个参数指出要读取的数据类型,第二个参数指出输入流使用的字符类型。

                   vector类有一个名为rbegin()的成员函数和一个名为rend()的函数,前者返回一个指向超尾的反向迭代器,后者返回一个指向第一个元素的反向迭代器。

                   下面是一个程序示例:

[cpp] view plaincopyprint?
  1. #include "stdafx.h"  
  2. #include <iostream>  
  3. #include <iterator>  
  4. #include <vector>  
  5.   
  6.   
  7. int _tmain(int argc, _TCHAR* argv[])  
  8. {  
  9.     using namespace std;  
  10.   
  11.     int casts[10] = {6,7,2,9,4,11,8,7,10,5};  
  12.     vector<int> dice(10);  
  13.   
  14.     copy(casts,casts + 10,dice.begin());  
  15.     cout << "Let the dice be cast!\n";  
  16.     ostream_iterator<int,char> out_iter(cout," ");  
  17.     copy(dice.begin(),dice.end(),out_iter);  
  18.     cout <<endl;  
  19.   
  20.     cout << "Implicit use of reverse iterator.\n";  
  21.     //rend() 返回一个指向第一个元素的反向迭代器  
  22.     copy(dice.rbegin(),dice.rend(),out_iter);  
  23.     cout << endl;  
  24.     vector<int>::reverse_iterator ri;  
  25.     for (ri = dice.rbegin(); ri != dice.rend(); ++ri)  
  26.     {  
  27.         cout << *ri << " ";  
  28.   
  29.     }  
  30.     cout << endl;  
  31.     return 0;  
  32. }  

              另外3种迭代器:back_insert_iterator、front_insert_iterator和insert_iterator也将提高STL算法的通用性。

back_insert_iterator将元素插入到容器尾部,而front_insert_iterator将元素插入到容器的前端。最后,insert_iterator将元素插入到insert_iterator构造函数的参数指定的位置前面。

               这些迭代器将容器类型作为模板参数,将实际的容器标识符作为构造函数参数。也就是说,要为名为dice的vector<int>容器创建一个back_insert_iterator,可以这样做:

[cpp] view plaincopyprint?
  1. back_insert_iterator<vector<int> > back_iter(dice);  

必须声明容器类型的原因是,迭代器必须使用合适的容器方法。back_insert_iterator的构造函数将假设传递给它的类型有一个push_back()方法。

下面是一个使用示例:

[cpp] view plaincopyprint?
  1. #include "stdafx.h"  
  2. #include <iostream>  
  3. #include <string>  
  4. #include <iterator>  
  5. #include <vector>  
  6.   
  7. int _tmain(int argc, _TCHAR* argv[])  
  8. {  
  9.     using namespace std;  
  10.   
  11.     string s1[4] = {"fine","fish","fashion","fate"};  
  12.     string s2[2] = {"busy","bats"};  
  13.     string s3[2] = {"silly","singers"};  
  14.   
  15.     vector<string> words(4);  
  16.     copy(s1,s1+4,words.begin());  
  17.     ostream_iterator<string,char>out (cout," ");  
  18.     copy(words.begin(),words.end(),out);  
  19.     cout << endl;  
  20.   
  21.     copy(s2,s2 + 2,back_insert_iterator<vector<string> >(words));  
  22.     copy(words.begin(),words.end(),out);  
  23.     cout << endl;  
  24.   
  25.     copy(s3,s3+2,insert_iterator<vector<string> > (words,words.begin()));  
  26.     copy(words.begin(),words.end(),out);  
  27.     cout << endl;  
  28.     return 0;  

原创粉丝点击