画师P站ID:61403923
标准库模板
STL提供了一组表示,容器,迭代器,算法,函数对象的模板.容器是一个与数组类似的单元,可以储存若干个类型相同的值.算法用来完成特定任务(如对数组进行排序)的处方;迭代器用来遍历容器里的对象,与能够遍历数组的指针类似,是广义的指针.函数对象是类似于函数的对象,可以是类对象或函数指针.
模板类Vector
可以创建vector对象; 将一个vector对象赋值给另一个,或者使用[]运算符来访问vector中的元素.头文件vector中定义了vector模板
举个书上的栗子,输入书名和评分:
对vector的操作
size(): 返回容器中的元素数目;
swap(): 交换两个容器的内存;
begin(): 返回一个指向容器中第一个元素的迭代器;
end(): 返回一个表示超过容器尾的迭代器;
什么是迭代器? 他是一个广义的指针(恩没错就是指针),可以对其执行类似指针的操作比如解引用,递增;每个容器都定义了适合的迭代器,一般是名为iterator的typedef,其作用域为整个类.比如声明一个vector的迭代器可以这样做:
前面说过超过容器尾的迭代器,那么什么是超过结尾呢(past-the-end)?它是一种迭代器,指向容器最后一个元素后面的那个元素的指针.end()成员函数表示超过结尾的位置,如果将迭代器设为容器的第一个元素,然后自加.则最终可将它到达容器结尾,从而遍历整个容器.
push_back()是一个方便的方法,他讲元素添加到矢量末尾,这样他讲负责管理内存,增加矢量的长♂度,使之容纳下新成员:
erase()方法可以删除是两种给定区间的元素.他接受两个迭代器的参数,这俩参数定义了要删除的区间.第一个迭代器指向区间的起始处,第二个指向区间的末尾.例如下列代码删除了[sco.bgein(),sco.begin()+2)区间内的元素:
inster()方法的功能与erase()相反,他接受三个迭代器参数,第一个指向了新元素的插入位置,第二三个迭代器定义了被插入区间,这个区间通常是另一个容器对象的一部分;就是把A容器的一部分复制出来,插入到B容器的某一位置;列入下列代码将new_v中的除了第一个元素之外所有的元素查到old_v矢量的第一个元素前面:
对Vector的其他操作
矢量模板并不包括如搜索,排序,随机排序等.STL从更广泛的角度定义了非成员函数(non-member)来执行这些操作.但有的时候,即使有执行相同任务的非成员函数,STL还会定义一个成员函数,因为有的操作使用特定的算法比使用通用的算法效率更高.比如Vector的swap()效率比非函数成员的swap()高;但非函数成员能交换俩类型不同的容器的内容;
三个具有代表性的STL函数:
for_each();
fandom_shuffle();
sort();
for_each()接受三个参数,前两个是定义容器中区间的迭代器,最后那个是指向函数的指针(函数对象).被指向的函数不能修改容器元素的值,这玩意可以代替for用:
random_suffle()该函数接受两个指定区间的迭代器参数,并随机排列该区间的元素,前提是该函数要求可以对容器任意访问,显然vector满足:
sort()函数也要求容器资呲随机访问.该函数有俩重载,一个接受两个定义区间的迭代器参数,并使用容器定义的<运算符容器内容进行升序排序.
但如果容器元素是用户自定义的,那么则要给你自定义的类填个<的重载,也就是operator<()
..比如我自定义了个结构或类Rev:
然后就可以对包含Review对象(如books)的矢量进行排序了:
上述程序是按照title成员的字母顺序排序的,如果title一样就按rating排序.如果想降序排序或者按照rating排序,可以使用另一种格式的sort().他接受三个参数,前两个参数也是指定区,间的迭代器,最后一个参数指向要使用的函数的指针(函数对象) 说白了就是函数名 而不去使用operator<().:
有了这函数之后就可以….将Rev对象的books矢量按照rating升序排列(你不说降序么)..:
上述代码与operator<()相比,WorseThan()函数对Rev的排序工作不是那么完整,WorsThan()中如果俩对象的title一样,则视为相同,这叫完整弱排序(strict weak ordering).而operator()中如果俩对象的title一样则比较rating,这叫全排序(total ordering);
基于范围的for循环
基于范围的for循环是为了STL而设计的:
在这种for循环中,括号内的代码声明一个与容里内容类型相同的变量,然后指出了容器名称,循环将使用指定的变量x依次访问容器的每个元素….
比如 for_each(books.begin(),books.end(),ShowStr);
可以写成:
不同于for_each(),基于范围的for循环能修改容器里的内容,你只需要指定一个引用参数: