STL 简介

通用编程技术(generic programming)

 

     面对对象编程关注的是编程的数据方面,而通用编程技术关注的是算法。它们之间的共同点是抽象和创建可重用代码。

 

     通用编程技术旨在编写独立于数据类型的代码。在C++中,完成通用程序的工具是模板。

 

STL

 

    STL提供了一组表示容器、迭代器、函数对象和算法的模板。

 

    容器是一个与数组类似的单元,可以存储若干个值。STL容器是同质的,即存储的值的类型相同。

 

    算法是完成特定任务(如对数组进行排序或在链表中查找特定值)的处方。

 

    迭代器能够用来遍历容器的对象,与能够遍历数组的指针类似,是广义指针。

 

    函数对象是类似于函数的对象,可以是类对象或函数指针(包括函数名,因为函数名被用作指针).

 

    STL使得能够构造各种容器(包括数组、队列和链表)和执行各种操作(包括搜索、排序和随机排列)。

 

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

    例如,vector模板的开头与下面类似:

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

 

    所有的STL容器都提供了一些基本方法,其中包括:
    size()——返回容器中元素数目、
    swap()——交换两个容器的内容、
    begin()——返回一个指向容器中第一个元素的迭代器、
    end()——返回一个表示超过容器尾的迭代器。

 

迭代器

 

    它是一个广义指针。它可以是指针,也可以是一个可对其执行类似指针的操作——如解除引用(如 operator*() )和递增(如operator++() )——的对象。

 

    对指向迭代器的指针进行广义化使得STL能够为各种不同的容器类(包括那些简单指针无法处理的类)提供统一的接口。

 

    每个容器类都定义了一个合适的迭代器,该迭代器的类型是一个名为iterator的typedef,其作用域为整个类。

 

例如,为vector的double类型规范声明一个迭代器:
vector<double>::iterator pd;      // pd an iterator

 

假设scores是一个vector<double>对象:
vector<double> scores;

 

则可以使用迭代器pd执行这样的操作:
pd = scores.begin();   // have pd point to the first element
*pd = 22.3;                // dereference pd and assign value to first element
++pd;                         // make pd point to the next element

 

    超过结尾(past-the-end)。它是一种迭代器,指向容器最后一个元素后面的那个元素。因此,如果scores和pd的定义与前面的范例中相同,则可以用下面的代码来显示容器的内容:
for (pd = scores.begin(); pd != scores.end(); pd++)
    cout << *pd << endl;

 

STL容器的其他方法

 

    比如vector模板类还包含一些只有某些STL容器才有的方法。

 

    push_back()方法将元素添加到容器末尾。这样做时,它将负责内存管理,增加容器的长度,使之能够容纳新的成员。

 

范例:
vector<double> scores;             // create an empty vector
double temp;
while (cin >> temp && temp >= 0)
     scores.push_back(temp);
cout << "You entered " << scores.size() << " scores./n";

 

    每次循环都给scores对象增加一个元素。在编写或运行程序时,无须了解元素的数目。只要能够取得足够的内存,程序就可以根据需要增加scores的长度。

 

    erase()方法删除容器中给定区间的元素。它接受两个迭代器参数,这些参数定义了要删除的区间。第一个迭代器指定区间的起始处,第二个迭代器位于区间终止处的后一个位置。

 

范例:
vector<double> scores(10);
scores.erase(scores.begin(), scores.begin()+2);

 

    上述代码将删除第一个和第二个元素,即删除begin()和begin()+1指向的元素(由于vector提供了随机访问功能,因此vector类迭代器定义了诸如begin()+2等操作)。

 

    区间[it1,it2]由迭代器it1和it2指定,其范围为it1到it2(不包括it2)。

 

    insert()方法接受3个迭代器参数,第一个参数指定了新元素的插入位置,第二个和第三个迭代器参数指定了被插入区间,该区间通常是另一个容器对象的一部分。

 

范例:
vector<int> old;
vector<int> new;
...
old.insert(old.begin(),new.begin()+1,new.end());

 

    上述代码将new对象中除第一个元素以外的所有元素插入到old对象的第一个元素的前面。

 

    使用超尾元素,将新元素附加到尾部:

    old.insert(old.end(),new.begin()+1,new.end());

 

STL非成员(non-member)函数

 

    STL从更广泛的角度定义了适用于所有容器类的非成员函数。

 

for_each()函数

    它接受3个参数,前两个是定义容器中区间的迭代器,最后一个是指向函数的指针(更普遍地说,最后一个参数是一个函数对象)。

 

    该函数将被指向的函数应用于容器区间中的各个元素。被指向的函数不能修改容器元素的值。

 

random_shuffle()函数

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

 

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

 

sort()函数

    该函数也要求容器支持随机访问。

 

    该函数有两个版本,第一个版本接受两个定义区间的迭代器参数,并使用为存储在容器中的类型元素定义的 < 操作符,对区间中的元素进行操作。

 

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


将按升序对coolstuff的内容进行排序,排序时使用内置的 < 操作符对值进行比较。

 

    如果容器元素是用户定义的对象,则要使用sort(),必须定义能够处理该类型对象的operator<()函数。

 

    第二个版本接受3个参数,前两个参数也是指定区间的迭代器,最后一个参数是指向要使用的函数的指针(函数对象)。修改了默认使用的operator<()函数,则可以使用用户自定义的方法进行排序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值