c++primer plus第十六章-标准模板类

c++primer plus第十六章-标准模板类


1)什么是STL?

2)模板类vector

3)分配器

4)什么是迭代器?

5)STL提供的一些基本方法

6)3个具有代表性的STL函数

7)泛型编程

8)迭代器的5种类型


1)什么是STL?

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

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


2)模板类vector

要创建vector模板对象,可使用通常的<type>表示法来指出要使用的类型。另外,vector模板使用动态内存分配,因此可以用初始化参数来指出需要多少矢量。

#include <vector>

using namespace std;

vector<int> ratings(5);  //a vector of 5 int

vector<dounle> scores(10);  //a vector of 10 doubles

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

cout<<scores[1]<<endl;


3)分配器

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

template<class T, class Allocator = allocator<T>>

class vector{... ...}

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


4)什么是迭代器?

它是一个广义指针。事实上,它可以是指针,也可以是一个可对其执行类似指针的操作-如解除引用(如operator*())和递增(如operator++())的对象。通过将指针广义化为迭代器,让stl能够为各种不同的容器类(包括那些简单指针无法处理的类)提供统一的接口。每个容器类都定义了一个合适的迭代器,该迭代器的类型是一个名为iterator的typedef,其作用域为整个类。

要为vector的double类型规范声明一个迭代器:

vector<double> ::iterator pd;

vector<double> scores;

pd = scores.begin();

*pd = 22.3;

++pd;


5)STL提供的一些基本方法:

size()--返回容器中元素数目;

swap()--交换两个容器的内容;

begin()--返回一个指向容器中第一个元素的迭代器;

end()--返回一个表示超过容器尾的迭代器;

push_back()--将元素添加到矢量末尾;

erase()--删除矢量中给定区间的元素;

insert()--插入元素


6)3个具有代表性的STL函数:

第一个:for_each()

接受3个参数,前两个是定义容器中区间的迭代器,最后一个是指向函数的指针。该函数将被指向的函数应用于容器区间中的各个元素。被指向的函数不能修改容器元素的值。可用来替换for循环:

vector<Review>::iterator pr;

for(pr=books.begin(); pr!=books.end();pr++)

ShowReview(*pr);

替换为:

for_each(books.begin(),books.end(),ShowReview);


第二个:Random_shuffle()

函数接受两个指向指定区间的迭代器参数,并随机排列该区间中的元素。下面随机排列books矢量中的所有元素:

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


第三个:sort()

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

vector<int> coolstuff;

...

sort(coolstuff.begin(),coolstuff.end());

如果容器是对象,则要使用operator<()函数。

第二个版本是接受3个参数,前两个参数也是指定区间的迭代器,最后一个参数是指向要使用的函数的指针(函数对象)。返回值可转换为bool,false表示两个参数的顺序不正确。


7)泛型编程的概念

旨在编写独立于数据类型的代码,在c++中,完成通用程序的工具是模板。当然,模板使得能够按泛型定义函数或类,而STL通过通用算法更进一步。模板让一切成为可能,但必须对元素进行仔细设计。

理解迭代器是理解STL的关键所在。模板使得算法独立于存储的数据类型,而迭代器使算法独立于使用的容器类型。


泛型编程旨在使用同一个find函数来处理数组、链表或任何其他容器类型。即函数不仅独立于容器中存储的数据类型,而且独立于容器本身的数据结构。模板提供了存储在容器中的数据类型的通用表示,因此还需要遍历容器中的值的通用表示,迭代器正是这样的通用表示。


8)迭代器的5种类型

第一:输入迭代器

即来自容器的信息被视为输入,就像来自键盘的信息对程序来说是输入一样。因此,输入迭代器可被程序用来读取容器中的信息。具体地说,对输入迭代器解除引用将是程序能够读取容器中的值,但不一定能让程序修改值。因此,需要输入迭代器的算法将不会修改容器中的值。

注意:输入迭代器是单向迭代器,可以递增,但不可以倒退。


第二:输出迭代器

STL使用术语“输出”来指用于将信息从程序传输给容器的迭代器,因此程序的输出就是容器的输入,输出迭代器与输入迭代器相似,只是解除引用让程序能够修改容器值,而不能读取。如果算法不用读取容器的内容就可修改它,则没有理由要求它使用能够读取内容的迭代器。

总之:对于单通行、只读算法,可以使用输入迭代器,而对于单通行、只写算法,就可以使用输出迭代器。


第三:正向迭代器

它总是按相同的顺序遍历一系列值。另外,将正向迭代器递增后,仍然可以对前面的迭代器值解除引用,并可以得到相同的值。这些特征使得多次通行算法成为可能。

正向迭代器既可以使得能够读取和修改数据,也可以使得只能读取数据。


第四:双向迭代器

第五:随机访问迭代器

有些算法(如标准排序和二分搜索)要求能够直接跳到容器中的任何一个元素,这叫随机访问。


9)容器概念

容器是存储其他对象的对象。被存储的对象必须是同一种类型,也可以是内置类型值。存储在容器中的数据为容器所有,这意味着当容器过期时,存储在容器中的数据也将过期。


不能将任何类型的对象存储在容器中,具体地说,类型必须是可复制构造的和可赋值的。基本类型满足这些要求,只要类定义没有将复制构造函数和赋值运算符声明为私有或保护的,则也满足这种要求。基本容器不能保证其元素都按特定的顺序存储,也不能保证元素的顺序不变。


10)七种序列容器类型

第一:vector

vector是数组的一种类型表示,它提供了自动内存管理功能,可以动态地改变vector对象的长度,并随着元素的添加和删除而增大和缩小。它提供了对元素的随机访问。在尾部添加和删除元素的时间是固定的,但在头部或中间插入和删除元素的复杂度为线性时间。

vector可以反转容器概念。rbegin()和rend(),前者返回一个指向反转序列的第一个元素的迭代器,后者返回反转序列的超尾迭代器。


第二:deque

deque模板类(在deque头文件中声明)表示双端队列,通常被简称为deque,在STL中,其实现类似于vector容器,支持随机访问,主要区别在于,从deque对象的开始位置插入和删除元素的时间是固定的,而不像vector中那样是线性时间的。所以,如果多数操作发生在序列的起始和结尾处,则应考虑使用deque数据结构。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值