标准模板库

  STL提供了一组表示容器、迭代器、函数对象和算法的模板。
  容器是一个与数组类似的单元。可以存储若干个值。STL容器是同质的,即存储的值的类型相同;
  算法是完成特定任务(如对数组进行排序或在链表中查找特定值)的方法;
  迭代器能够用来遍历容器的对象,与能够遍历数组的指针类似,是广义指针;
  函数对象是类似于函数的对象,可以是类对象或函数指针(包括函数名,因为函数名被用作指针)。
  STL使得能够构造各种容器(包括数组、队列和链表)和执行各种操作(包括搜索、排序和随机排列)。

STL不是面向对象的编程,而是一种不同的编程模式——泛型编程。

模板类vector

#include <vector>
using namespace std;
vector<int> rating(5);

由于运算符[]被重载,因此创建vector对象后,可使用通常的数组表示法来访问各个元素。

分配器
  与string类相似,各种STL容器模板都接受一个可选的模板参数。该参数指定使用哪个分配器对象来管理内存。例如:

template <class T, class Allocator = allocator<T>>
	class  vector { ... }

如果省略该模板参数,则容器模板将默认使用allocator类。这个类使用new和delete。

可对矢量执行的操作
  所有的STL容器都提供了一些基本方法,其中包括:
size():返回容器中元素数目;
swap():交换两个容器的内容;
begin():返回一个指向容器中第一个元素的迭代器;
end():返回一个表示超过容器尾的迭代器;
  通过将指针广义化为迭代器,让stl能够为各种不同的容器类提供统一的接口。每个容器类都定义了一个合适的迭代器,该迭代器的类型是一个名为iterator的typedef,其作用域为整个类。

vector<double>::iterator pd;
vector<double> scores;
//迭代器pd的行为就像指针一样
pd = scores.begin();
*pd = 22.9;
++pd;

C++11的自动类型推断可以简化上面的代码

vector<double> scores;
auto pd = scores.begin();
*pd = 22.9;
++pd;

push_back():将元素添加到矢量末尾;
erase():删除矢量中给定区间的元素。它接受两个迭代器参数;这些参数定义了要删除的区间。
insert():它接受2个迭代器参数,第一个参数指定来了新元素的插入位置,第二个和第三个迭代器参数定义了被插入区间,该区间通常是另一个容器对象的一部分。

对矢量可执行的其它操作
  我们通常对数组执行很多操作,如搜索、排序、随机排序。矢量模板没有包含这些常见的操作,没有! STL从更广泛的角度定义看非成员函数来执行这些操作。即不是为每个容器类定义find()成员函数。而是定义一个适用于所有容器的非成员函数find()。这种设计理念省去了大量重复的工作。
  另一方面,即使有执行相同任务的非成员函数,STL有时也会定义一个成员函数。这是因为对有些操作来说,类特定算法的效率比通用算法高。因此vector的成员函数swap的效率比非成员函数swap高,但非成员函数能交换两个类型不同的容器的内容。

下面介绍3个具有代表性的STL函数:for_each()、random_shuffle()和sort()。
• for_each()函数可以用于很多容器类,它接受3个参数,前两个定义容器中区间的迭代器,最后一个是指向函数的指针。for_each()将被指向的函数应用于容器区间中的各个元素。被指向的函数不能修改容器元素的值。可以用for_each()来替换for循环。

vector<Review>::iterator pr;
for (pr = books.begin(); pr != books.end(), pr++)
	ShowReview(*pr);
//for_each()替换for。可避免显式使用迭代器变量
for_each(books.begin(), books.end(), ShowReview);

• random_shuffle()函数接受两个指定区间的迭代器参数,并随机排列该区间中的元素。

random_shuffle(books.begin(), books.end())

该函数与可用于任何类的for_each不同,该函数要求容器允许随机访问。vector类可以。

• sort()函数也要求容器支持随机访问。该函数有两个版本,第一个版本接受两个定义区间的迭代器参数,并使用为存储在容器中的类型元素定义的<运算符,对区间中的元素进行操作>,例如下面的示例按升序排序时,使用内置的 < 运算符对值进行比较:

vector<int> coolstuff;
...
sort(coolstuff.begin(), coolstuff.end())

  如果类型是用户定义的对象,则需要使用sort(),必须定义能够处理该类型对象的operator<()函数。
另外一个版本的sort(),它接受3个参数,前两个参数也是指定区间的迭代器,最后一个参数是指向要使用的函数的指针(函数对象),而不是用于比较operator<()。

bool WorseThan(const Review & r1, const Review & r2)
{
	if (r1.rating < r2.rating)
		return true;
	else
		return false;
}

sort(books.begin(), books.end(), WorseThan);

基于范围的for循环(C++11)
  基于范围的for循环是为用于STL而设计的。

double prices[5] = {4.99, 10.99, 6.85, 7.89, 8.46};
for (double x : prices)
	cout << x << endl;

  在这种for循环中,括号内的代码声明一个类型与容器存储的内容相同的变量,然后指出了容器的名称。接下来,循环体使用指定的变量依次访问容器的每个元素。

for_each(books.begin(), books.end(), ShowReview);
//用下述基于范围的for循环替换
for (auto x : books) ShowReview(x);

  编译器将推断出x的类型为Review,而循环将依次将books中的每个Review对象传递给ShowReview()。
  不同于for_each(),基于范围的for循环可修改容器的内容,指定一个引用参数。

下一节——泛型编程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值