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

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

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. [Algorithm]巧用多项式系数与进制的联系

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  2. day2逻辑运算作业详解

    1.day2题目 1.判断下列逻辑语句的True,False. 1)1 > 1 or 3 < 4 or 4 > 5 and 2 > 1 and 9 > 8 or 7 &l ...

  3. redis之安装

    redis之安装 redis redis介绍 redis是一个key-value存储系统,菲关系型数据库.和Memcached类似,他支持存储的value类型相对更多,包括字符串.列表.哈希散列表.集 ...

  4. codevs1026-dp(记忆化搜索)

    题目描述 Description 年轻的拉尔夫开玩笑地从一个小镇上偷走了一辆车,但他没想到的是那辆车属于警察局,并且车上装有用于发射车子移动路线的装置. 那个装置太旧了,以至于只能发射关于那辆车的移动 ...

  5. Java通过图片url地址获取图片base64位字符串的两种方式

    工作中遇到通过图片的url获取图片base64位的需求.一开始是用网上的方法,通过工具类Toolkit,虽然实现的代码比较简短,不过偶尔会遇到图片转成base64位不正确的情况,至今不知道为啥. 之后 ...

  6. Jexus 5.8.2

    Jexus 5.8.2 正式发布为Asp.Net Core进入生产环境提供平台支持   Jexus 是一款运行于 Linux 平台,以支持  ASP.NET.PHP 为特色的集高安全性和高性能为一体的 ...

  7. Codeforces Round #377 (Div. 2) E. Sockets

    http://codeforces.com/contest/732/problem/E 题目说得很清楚,每个电脑去插一个插座,然后要刚好的,电脑的power和sockets的值相同才行. 如果不同,还 ...

  8. cordova开发的坑

    相机 根据android版本,有各种问题. 1.拍照后不会自动清内存造成内存溢出,导致照片不会自动旋转,拍多张之后会自动刷新网页. 2.小米手机安卓7.0时,拍出的照片不会自动旋转,需要安卓端代码调整 ...

  9. JAVA 框架之面向对象设计原则

     面向对象设计原则:  单一职责原则 SRP :   一个类或者行为只做一件事 .  降低代码冗余,提高可重用性,可维护性,可扩展性,可读性 使用组合形式   里氏替换原则 LSP :  所有引用基类 ...

  10. 【转】monkey实战--测试步骤、常用参数、常规monkey命令

    monkey实战--测试步骤.常用参数.常规monkey命令   简要步骤:adb devices---了解包名--adb shell monkey -p 包名 -v 运行次数(多个参数的组合形成不同 ...