现在的位置: 首页 > 综合 > 正文

使用标准模板库 (STL)之二

2014年07月07日 ⁄ 综合 ⁄ 共 2939字 ⁄ 字号 评论关闭

 

容器迭代器

尽管C++指针也是迭代器,但用的更多的是容器迭代器。容器迭代器用法和iterdemo.cpp一样,但和将迭代器申明为指针变量不同的是,你可以使用容器类方法来获取迭代器对象。两个典型的容器类方法是begin()和end()。它们在大多数容器中表示整个容器范围。其他一些容器还使用rbegin()和rend()方法提供反向迭代器,以按反向顺序指定对象范围。

下面的程序创建了一个矢量容器(STL的和数组等价的对象),并使用迭代器在其中搜索。该程序和前一章中的程序相同。

Listing 2. vectdemo.cpp

#include <iostream.h>#include <algorithm>#include <vector> using namespace std; vector<int> intVector(100); void main(){ intVector[20] = 50; vector<int>::iterator intIter =    find(intVector.begin(), intVector.end(), 50); if (intIter != intVector.end())   
cout << "Vector contains value " << *intIter << endl; else    cout << "Vector does not contain 50" << endl;}

注意用下面的方法显示搜索到的数据:

cout << "Vector contains value " << *intIter << endl;常量迭代器

和指针一样,你可以给一个迭代器赋值。例如,首先申明一个迭代器:

vector<int>::iterator first;

该语句创建了一个vector<int>类的迭代器。下面的语句将该迭代器设置到intVector的第一个对象,并将它指向的对象值设置为123::

first = intVector.begin();*first = 123;

这种赋值对于大多数容器类都是允许的,除了只读变量。为了防止错误赋值,可以申明迭代器为:

const vector<int>::iterator result;result = find(intVector.begin(), intVector.end(), value);if (result != intVector.end()) *result = 123; // ???

警告

另一种防止数据被改变得方法是将容器申明为const类型。

『呀!在VC中测试出错,正确的含义是result成为常量而不是它指向的对象不允许改变,如同int *const p;看来这作者自己也不懂』

使用迭代器编程

你已经见到了迭代器的一些例子,现在我们将关注每种特定的迭代器如何使用。由于使用迭代器需要关于STL容器类和算法的知识,在阅读了后面的两章后你可能需要重新复习一下本章内容。

输入迭代器

输入迭代器是最普通的类型。输入迭代器至少能够使用==和!=测试是否相等;使用*来访问数据;使用++操作来递推迭代器到下一个元素或到达past-the-end 值。

为了理解迭代器和STL函数是如何使用它们的,现在来看一下find()模板函数的定义:

template <class InputIterator, class T>InputIterator find( InputIterator first, InputIterator last, const T& value) {    while (first != last && *first != value) ++first;    return first; }

注意

在find()算法中,注意如果first和last指向不同的容器,该算法可能陷入死循环。

输出迭代器

输出迭代器缺省只写,通常用于将数据从一个位置拷贝到另一个位置。由于输出迭代器无法读取对象,因此你不会在任何搜索和其他算法中使用它。要想读取一个拷贝的值,必须使用另一个输入迭代器(或它的继承迭代器)。

Listing 3. outiter.cpp

#include <iostream.h>#include <algorithm>   // Need copy()#include <vector>      // Need vector using namespace std; double darray[10] = {1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9}; vector<double> vdouble(10); int main(){ vector<double>::iterator outputIterator
= vdouble.begin(); copy(darray, darray + 10, outputIterator); while (outputIterator != vdouble.end()) {    cout << *outputIterator << endl;    outputIterator++; } return 0;}

注意

当使用copy()算法的时候,你必须确保目标容器有足够大的空间,或者容器本身是自动扩展的。

前推迭代器

前推迭代器能够读写数据值,并能够向前推进到下一个值。但是没法递减。replace()算法显示了前推迭代器的使用方法。

template <class ForwardIterator, class T>void replace (ForwardIterator first,              ForwardIterator last,              const T& old_value,              const T& new_value);

使用replace()将[first,last]范围内的所有值为old_value的对象替换为new_value。:

replace(vdouble.begin(), vdouble.end(), 1.5, 3.14159);双向迭代器

双向迭代器要求能够增减。如reverse()算法要求两个双向迭代器作为参数:

template <class BidirectionalIterator>void reverse (BidirectionalIterator first,              BidirectionalIterator last);

使用reverse()函数来对容器进行逆向排序:

reverse(vdouble.begin(), vdouble.end());随机访问迭代器

随机访问迭代器能够以任意顺序访问数据,并能用于读写数据(不是const的C++指针也是随机访问迭代器)。STL的排序和搜索函数使用随机访问迭代器。随机访问迭代器可以使用关系操作符作比较。

random_shuffle() 函数随机打乱原先的顺序。申明为:

template <class RandomAccessIterator>void random_shuffle (RandomAccessIterator first,                     RandomAccessIterator last);

使用方法:

random_shuffle(vdouble.begin(), vdouble.end()); 

抱歉!评论已关闭.