元素在顺序容器中的顺序与其加入容器时的位置相对应。关联容器中元素的位置由元素相关联的关键字值决定。所有容器类都共享公共的接口,不同容器按不同方式对其进行扩展。

  一个容器就是一些特定类型对象的集合。顺序容器为程序员提供了控制元素存储和访问顺序的能力。

1. 顺序容器概述

容器的两种性能:

  • 向容器中添加或删除元素的代价
  • 非顺序访问容器中元素的代价

顺序容器类型:

如何确定使用哪种顺序容器

NOTE:通常情况下,使用vector是最好的选择。根据使用的需求对容器的哪种性能更加看重来选择合适的容器。

2. 容器库概览

容器类型上的操作有三个层次:

  • 某些操作是所有容器类型都提供的
  • 另外一些操作仅针对顺序容器、关联容器或无序容器
  • 还有一些操作只适用于一小部分容器

每个容器都定义在一个头文件中,文件名与类型名相同。容器均定义为模板类。

以下容器操作是所有容器类型所共有的操作

2.1 迭代器

迭代器范围

一个迭代器范围由一对迭代器表示,begin指向容器的首元素,end指向容器的尾元素之后的位置。

迭代器范围是一个左闭合区间,[begin, end)。

begin可以和end指向同一个位置,但是end不能指向begin之前的位置。

2.2 容器类型成员

处理迭代器之外还有反向迭代器,对反向迭代器进行++操作,会得到上一个元素。

通过value_type得到元素类型,通过reference或const_reference得到元素类型的一个引用。

2.3 标准库array具有固定大小

与内置数组一样,array的大小也是类型的一部分。定义array时,除了指定元素类型,还要指定容器大小。

array<int, 42>  arr;

其构造函数和数组差不多,列表初始化时,列表元素不要超过array的大小,可以少,array剩下的元素就进行值初始化。

array<int, 10> a={1,2,3};

剩下的7个元素值初始化为0;

此外还可以对array进行拷贝或对象赋值操作,但内置数组是不支持的

int a1[3]={0,1,2};
int a2[3]=a1; //错误
array<int, 3> a3={0,1,2};
array<int, 3> a4=a3; //正确

拷贝或赋值要保证类型相同。

2.4 赋值和swap

注意array在初始化的时候可以进行列表初始化,但是赋值的时候不能将一个花括号列表赋值给它。

NOTE:array赋值的时候,两边的运算对象必须具有相同的类型。

array<int, 3> a1 = { 0, 1, 2 };
array<int, 3> a2 = { 0 };
array<int, 3> a3 = { 2, 3, 4 };
a1 = a2;
a3 = { 0 }; //错误

对a3赋值的时候,a3的类型是array<int,3>,而右边是先把{0}转换成临时变量array<int,1> tmp,然后再将tmp赋值给a3,这是tmp和a3类型不一致。

由于可能因为大小不一致导致类型不一致,array不支持容器的赋值运算assign。

NOTE:assign操作仅适合顺序容器

赋值运算符要求左右两边的运算对象具有相同的类型,将右边运算对象所有元素拷贝到左边运算对象中。

swap

swap交换两个相同类型容器的内容。swap操作并不会交换元素本身,知识交换两个容器的内部数据结构(除array外)。这就意味着,指向容器的迭代器、引用和指针在swap操作之后都不会失效,仍指向swap操作之前的那些元素,只是这些元素属于不同容器了。

swap两个array会真正交换他们的元素。

有两个版本的swap:成员函数版本以及非成员版本,统一使用非成员版本的swap。

2.5 容器大小操作

  • size:forward_list不支持size
  • empty
  • max_size

2.6 关系运算符

每个容器类型都支持相等运算符(=和!=),除了无序容器外都支持关系运算符。关系运算符两边的运算对象必须是相同类型的容器,且必须保存相同类型的元素。

关系比较规则:

对元素进行逐对比较。大小相同、对应元素相等则相等;元素相等,大小不等,小的小于大的;都不相等,则比较第一个不相等的元素。

NOTE:只有当容器的元素定义了相应的比较运算符操作时,才可以使用关系运算符。

3. 顺序容器操作

顺序容器和关联容器的不同之处在于两者组织元素的方式。这些不同之处直接关系到了元素如何存储、访问、添加以及删除。接下来的操作都是顺序容器所独有的操作。

3.1 向顺序容器中添加元素

新标准引入了三个新成员:emplace_front 、emplace和emplace_back,这些操作构造而不是拷贝元素。

当调用push或insert成员函数时,我们将元素类型的对象传递给它们,这些对象被拷贝到容器中。而当我们调用emplace成员函数时,则是将参数传递给元素类型的构造函数。

empalce函数的参数根据元素类型而变化,参数必须与元素类型的构造函数相匹配。

c.empalce("978-001",25,15.99);    //用三个参数直接构造对象
c.push_back("978-001",25,15.99); //错误,没有接受三个参数的push_back版本
c.push_back(Sales_data("978-001",25,15.99)); //正确

NOTE:emplace函数在容器中直接构造元素,而push_back则是创建临时对象。

3.2 访问元素

访问成员函数返回的是引用

front、back、下标和at,其返回的都是引用。

如果我们使用auto变量来保存这些函数的返回值,并且希望使用此变量来改变元素的值,必须记得将变量定义为引用类型。

auto &v=c.back();    //获得指向最后一个元素的引用
auto v=c.back(); //v不是一个引用,是c.back()的一个拷贝

下标操作必须保证在范围内操作

3.3 删除元素

3.4 特殊的forward_list操作

forward_list并未定义insert、emplace和erase,而是定义了名为insert_after、emplace_after和erase_after的操作。

3.5 改变容器大小

list<int> ls(10,45);    //10个int,都是45
ls.resize(15); //将5个值为0的元素添加到ls的末尾
ls.resize(25,-1); //将10个值为-1的元素添加到ls的末尾
ls.resize(5); //从ls末尾删除20个元素

3.6 容器操作可能使迭代器失效

由于向迭代器添加元素和从迭代器删除元素的代码可能会使迭代器失效,因此必须保证每次改变容器的操作之后都正确地重新定位迭代器。

4. vector对象是如何增长的

每次都比实际所需空间多分配点空间,而不是每次都把所有元素移动到新空间。

管理容量的成员函数

capacity和size

size是指已经保存的元素的数目;而capacity则是在不分配新的内存空间的前提下它最多可以保存多少元素。

NOTE:只有当迫不得已时才可以分配新的内存空间。

5. 额外的string操作

5.1 构造string的其他方法

string定义的这些额外操作要么是提供string类和C风格字符数组之间的相互转换,要么是增加了允许我们用下标代替迭代器的版本。

substr操作

substr返回一个string,它是原始string的一部分或全部的拷贝,可以传递给substr一个可选的开始位置和计数值。

5.2 改变string的其他方法

string类型支持顺序容器的赋值运算符以及assign、insert和erase操作。除此之外,还定义了额外的insert和erase版本。

s.insert(s.size(),5,'!');    //在s末尾插入5个感叹号
s.erase(s.size()-5,5); //从s删除最后5个字符 const char *cp="Stately, plump Buck";
s.assign(cp,7); //s=="Stately"
s.insrt(s.size(),cp+7); //s=="Stately, plump Buck" string s="some string", s2="some other string";
s.insert(0,s2); //在s中位置0之前插入s2的拷贝
s.insert(0,s2,0,s2.size());

5.3 string搜索操作

搜索是大小写敏感的

逆向搜索

rfind成员函数搜索最后一个匹配,即子字符串最靠右的出现位置。

5.4 compare函数

5.5 数值转换

6. 容器适配器

除了顺序容器外,标准库还定义了三个顺序容器适配器:stack、queue和priority_queue。容器、迭代器和函数都有适配器。

本质上,一个适配器是一种机制,能使某种事物的行为看起来像另一种事物一样。

一个容器适配器接受一种已有的容器类型,使其行为看起来像一种不同的类型。

C++系统学习之九:顺序容器的更多相关文章

  1. C++学习基础四——顺序容器和关联容器

    —顺序容器:vector,list,queue1.顺序容器的常见用法: #include <vector> #include <list> #include <queue ...

  2. 【mongodb系统学习之九】mongodb保存数据

    九.mongodb保存数据: 1).插入.保存数据:insert:语法db.collectionName.insert({"key":value}),key是字段名,必须是字符串( ...

  3. Linux系统学习 十九、VSFTP服务—虚拟用户访问—为每个虚拟用户建立自己的配置文件,单独定义权限

    为每个虚拟用户建立自己的配置文件,单独定义权限 可以给每个虚拟用户单独建立目录,并建立自己的配置文件.这样方便单独配置权限,并可以单独指定上传目录 1.修改配置文件 vi /etc/vsftpd/vs ...

  4. 系统学习 Java IO (九)----缓冲流 BufferedInputStream/BufferedOutputStream

    目录:系统学习 Java IO---- 目录,概览 BufferedInputStream BufferedInputStream 类为输入流提供缓冲. 缓冲可以加快IO的速度. BufferedIn ...

  5. Docker学习(九)Volumn容器间共享数据

    Docker学习(九)Volumn容器间共享数据 volume是什么 volume在英文中是容量的意思, 在docker中是数据卷的意思,是用来保存数据的容器 为什么要进行数据共享 在集群中有多台to ...

  6. Docker 容器数据 持久化(系统学习Docker05)

    写在前面 本来是可以将数据存储在 容器内部 的.但是存在容器内部,一旦容器被删除掉或者容器毁坏(我亲身经历的痛,当时我们的大数据平台就是运行在docker容器内,有次停电后,不管怎样容器都起不来.以前 ...

  7. c++ 顺序容器学习

    所谓容器,就是一个装东西的盒子,在c++中,我们把装的东西叫做“元素” 而顺序容器,就是说这些东西是有顺序的,你装进去是什么顺序,它们在里面就是什么顺序. c++中的顺序容器一共有这么几种: vect ...

  8. 【c++ Prime 学习笔记】第9章 顺序容器

    一个容器是特定类型对象的集合 顺序容器中元素的顺序与其加入容器的位置对应 关联容器中元素的顺序由其关联的关键字决定,关联容器分为有序关联容器和无序关联容器 所有容器类共享公有接口,不同容器按不同方式扩 ...

  9. Unity3D 装备系统学习Inventory Pro 2.1.2 基础篇

    前言 前一篇 Unity3D 装备系统学习Inventory Pro 2.1.2 总结 基本泛泛的对于Inventory Pro 这个插件进行了讲解,主要是想提炼下通用装备系统结构和类体系.前两天又读 ...

随机推荐

  1. day7计算作业详解

    1.day7题目 1.判断一个数是否是水仙花数, 水仙花数是一个三位数, 三位数的每一位的三次方的和还等于这个数. 那这个数就是一个水仙花数, 例如: 153 = 13 + 53 + 3**3 2.给 ...

  2. 微信站 - 实现复制功能 clipboard

    <script src="https://cdn.bootcss.com/clipboard.js/1.5.9/clipboard.js"></script> ...

  3. STP-11-多生成树:IEEE 802.1s

    IEEE802.1s多生成树(MultipleSpanningTrees,MST)有时也称为多STP(MultipleSTP,MSTP),它定义了在使用802.1QVLAN网络中,部署多实例STP的标 ...

  4. vue中做出购物车的功能

    效果展示: 一:html结构 <div id="buyButton" class="btn-buy"> <button onclick=&qu ...

  5. Linux操作学习笔记1

    Linux只有一个根目录/,所有的文件和设备都当成是文件进行管理: pwd 打印当前工作目录 (print working directory) whoami ls  列出当前目录面的文件 ls -l ...

  6. 2017浙江工业大学-校赛决赛 BugZhu抽抽抽!!

    Description 当前正火的一款手游阴阳师又出新式神了,BugZhu十分想要获得新出的式神,所以他决定花光所有的积蓄来抽抽抽!BugZhu经过长时间的研究后发现通过画三角外接圆能够提高获得该式神 ...

  7. Netty(4)Stream by codec(粘包与拆包)

    TCP/IP,传输的是byte[],将byte[]放入队列中.可能会发生粘包和拆包. 比如,客户端向服务端发送了2条消息,分别为D1,D2,可能产生的情况,如下图所示: 情况一:正常的. 情况二:粘包 ...

  8. CoreCLR源码2

    CoreCLR源码 前一篇我们看到了CoreCLR中对Object的定义,这一篇我们将会看CoreCLR中对new的定义和处理new对于.Net程序员们来说同样是耳熟能详的关键词,我们每天都会用到ne ...

  9. (转)Inode详解

    Inode详解  原文:http://www.cnblogs.com/adforce//p/3522433.html 一.inode是什么 理解inode,要从文件储存说起. 文件储存在硬盘上,硬盘的 ...

  10. centos6.3搭建FTP服务器图文教程

    今天下午不忙,没什么事,看到我大红盟linux版块如此冷清,心不能忍,做了个FTP服务器的搭建教程,大家可以看看, 不会做视频,就图文交叉了,写得不好,望谅解.以后有时间再出一个LNMP的教程. 不磨 ...