C++ Primer 第3章 字符串、向量和数组(2)

3.3 标准库类型vector

标准库类型vector表示对象的集合,其中所有对象的类型都相同。集合中的每个对象都有一个与之对应的索引,索引用于访问对象。因为vector容纳着其他对象,所以也常被称作容器。
C++语言既有类模板,也有函数模板,其中vector是一个类模板。模板本身不是类或函数,相反可以将模板看作为编译器生成类或函数编写的一份声明。编译器根据模板创建类或函数的过程称为实例化,对于类模板,通过提供一些额外信息来指定模板到底实例化成什么样的类,提供信息的方式:在模板名字后面跟一对尖括号,在括号内放上信息,例如:vector ivec; //ivec保存int类型的对象。

3.3.1 定义和初始化vector对象


列表初始化vector对象
用花括号括起来的0个或多个初始元素值被赋给vector对象。
创建指定数量的元素
用vector对象容纳的元素数量和所有元素的统一初始值来初始化vector对象:vector< int > ivec(10,-1); //10个int类型的元素,每个都被初始化为-1.
通常可以只提供vector对象容纳的元素数量而略去初始值。此时库会创建一个值初始化的元素初值,并把它赋给容器中的所有元素。但是如果vector对象中元素的类型不支持默认初始化,我们就必须提供初始的元素值。vector< string > svec(10); //10个元素,每个都是空string对象。
花括号一般是列表初始化,花括号中的值必须与元素类型相同。如果初始化时使用了花括号的形式但是提供的值又不能用来列表初始化,就要考虑用这样的值来构造vector对象了,这是就类似于圆括号了。vector< string > v8{10,“hi”}; //v8有10个值为“hi”的元素。

3.3.2 向vector对象中添加元素

先创建一个空vector,然后在运行时再利用vector的成员函数push_back向其中添加元素。push_back负责把一个值当成vector对象的尾元素压到(push)vector对象的尾端(back)。

3.3.3 其他vector操作


访问vector对象中元素的方法和访问string对象中字符串的方法差不多。可以使用范围for语句处理vector对象中的所有元素
vector的empty和size两个成员与string的同名成员功能完全一致:empty返回布尔值,size返回值的类型是由vector定义的size_type类型。要使用size_type,需要先指定它是由哪种类型定义的,vector对象的类型总是包含着元素的类型:vector< int >::size_type //正确的。
计算vector内对象的索引
使用下标运算符能获取到指定的元素。下标从0开始,下标的类型是相应的size_type类型。
vector对象(以及string对象)的下标运算符可用于访问已存在的元素,而不能用于添加元素,只能对已存在的元素执行下标操作。

3.4 迭代器介绍

迭代器提供了对对象的间接访问,其对象是容器中的元素或者string对象中的字符。

3.4.1 使用迭代器

有迭代器的类型同时拥有返回迭代器的成员。这些类型都拥有begin和end成员,其中begin成员负责返回指向第一个元素的迭代器,end成员则负责返回指向容器“尾元素的下一位置”的迭代器,称为尾后迭代器,该迭代器指示的是容器的一个本不存在的“尾后”元素,并没有什么实际含义,仅仅是个标记而已,表示我们已经处理完了容器中的所有元素。如果容器为空,则begin和end返回的都是尾后迭代器。

迭代器运算符

将迭代器从一个元素移到另外一个元素
迭代器使用递增(++)运算符从一个元素移到下一个元素。因为end返回的迭代器并不实际指示某个元素,所以不能对其进行递增或者解引用的操作。
迭代器的类型
那些拥有迭代器的标准库类型使用iterator和const_interator来表示迭代器的类型,const_interator能读取但不能它所指的元素值,interator的对象可读可写。如果vector对象或string对象是常量,只能使用const_interator,如果不是常量,两个都可以用。

begin和end运算符
如果对象是常量,begin和end返回const_interator,如果不是常量,返回interator。如果对象只需读操作而无需写操作的话最好使用常量类型。C++11引入两个新函数,cbegin和cend,不论对象是否为常量,返回值都是const_interator类型。
结合解引用和成员访问操作
解引用迭代器可获得迭代器所指的对象,如果该对象的类型恰好是类,就有可能希望进一步访问它的成员。箭头运算符把解引用和成员访问两个操作结合在一起,it->mem和(*it).mem表达的意思相同。

某些对vector对象的操作会使迭代器失效
任何一种可能改变vector对象容量的操作,比如push_back,都会使该vector对象的迭代器失效。但凡是使用了迭代器的循环体,都不要向迭代器所属的容器添加元素。

3.4.2 迭代器运算

string和vector的迭代器提供了更多额外的运算符,一方面可使得迭代器的每次移动跨过多个元素,另外也支持迭代器进行关系运算,称为迭代器运算。
在这里插入图片描述
使用迭代器运算的一个经典算法是二分搜索。

发布了16 篇原创文章 · 获赞 11 · 访问量 647

猜你喜欢

转载自blog.csdn.net/qq_42820853/article/details/104460480
今日推荐