c++ STL之通用编程技术

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

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

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

                 1.输入迭代器

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

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

                 2.输出迭代器

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

                  3.正向迭代器

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

                   4.双向迭代器

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

                   5.随机访问迭代器

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

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

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

                     例如:

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

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

使用示例:

include<iterator>
....
ostream_iterator<int,char>out_iter(cout," ");
说明:

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

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

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

                   下面是一个程序示例:

#include "stdafx.h"
#include <iostream>
#include <iterator>
#include <vector>


int _tmain(int argc, _TCHAR* argv[])
{
	using namespace std;

	int casts[10] = {6,7,2,9,4,11,8,7,10,5};
	vector<int> dice(10);

	copy(casts,casts + 10,dice.begin());
	cout << "Let the dice be cast!\n";
	ostream_iterator<int,char> out_iter(cout," ");
	copy(dice.begin(),dice.end(),out_iter);
	cout <<endl;

	cout << "Implicit use of reverse iterator.\n";
	//rend() 返回一个指向第一个元素的反向迭代器
	copy(dice.rbegin(),dice.rend(),out_iter);
	cout << endl;
	vector<int>::reverse_iterator ri;
	for (ri = dice.rbegin(); ri != dice.rend(); ++ri)
	{
		cout << *ri << " ";

	}
	cout << endl;
	return 0;
}

              另外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,可以这样做:

back_insert_iterator<vector<int> > back_iter(dice);

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

下面是一个使用示例:

#include "stdafx.h"
#include <iostream>
#include <string>
#include <iterator>
#include <vector>

int _tmain(int argc, _TCHAR* argv[])
{
	using namespace std;

	string s1[4] = {"fine","fish","fashion","fate"};
	string s2[2] = {"busy","bats"};
	string s3[2] = {"silly","singers"};

	vector<string> words(4);
	copy(s1,s1+4,words.begin());
	ostream_iterator<string,char>out (cout," ");
	copy(words.begin(),words.end(),out);
	cout << endl;

	copy(s2,s2 + 2,back_insert_iterator<vector<string> >(words));
	copy(words.begin(),words.end(),out);
	cout << endl;

	copy(s3,s3+2,insert_iterator<vector<string> > (words,words.begin()));
	copy(words.begin(),words.end(),out);
	cout << endl;
	return 0;
}


参考书籍c++ primer plus 第五版中文版

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值