《c++ primer笔记》第九章 顺序容器

news2024/9/23 15:03:38

前言

知识点很多,这里只记录遗忘的。从这章开始会对前面章节的内容进行一个扩充,如果以前的忘了读起来会有点吃力。总的来说,本章节难度不大。

文章目录

    • 一、概述
    • 二、容器库概览
      • 2.1容器定义和初始化
      • 2.2赋值
    • 三、顺序容器操作
      • 3.1添加元素
      • 3.2删除元素
      • 3.3forward_list
      • 3.4容器操作使迭代器失效
    • 四、vector对象是如何增长的
    • 五、string操作
      • 5.1构造string 的其他方法
      • 5.2改变string的其他方法
      • 5.3string搜索操作
      • 5.4compare函数
      • 5.5数值转换
    • 六、容器适配器

一、概述

​ 顺序容器一共有六种类型:vector、deque、list、forward_list、array、string。下图是它们的一些特性。除了固定大小的array外,其他容器都提供高效、灵活的内存管理。vector、string和array之所以支持快速随机访问,是因为它们的元素存储在连续的内存空间中,所以进行插入删除操作就会很慢。而forward_list和list正好相反,它们存储元素的内存空间都是离散的,因此访问元素的开销较大。deque相对来说访问速度和某些情况的插入删除操作都比较高效。

array和forward_list都是C++11增加的新特性。array相对内置数组,效果更高、更安全。forward_list设计是为了达到与手写单向链表的性能。新标准库的容器优于旧版本。

image-20230307203401211

二、容器库概览

2.1容器定义和初始化

​ 将一个新容器创建为另一个容器的拷贝的方法:1)直接拷贝整个容器(两个容器的类型必须相同);2)拷贝一个由迭代器指定的元素范围(array除外)(两个迭代器的类型可以不同,只要元素能够转换)

image-20230307210016181

与顺序容器大小相关的构造函数

​ 如果元素类型是内置类型或者是具有默认构造函数的类类型,可以只为构造函数提供一个容器大小参数。如果元素没有默认构造函数,除了大小参数外,还必须指定一个显式的元素初始值。

array

array与内置数组很相似,当定义一个array时,除了指定元素类型,还要指定容器大小。

array<int, 42> 
array<string, 10>

一个默认构造的array是非空的,如果我们对array进行列表初始化,初始值的数目必须等于或小于array的大小。内置数组不能对其进行拷贝或对象赋值操作,但是array没有限制

int d[3] = {1,2,3};
int c[3] = d[3]; // 错误
array<int, 3> d2 = {1,2,3};
array<int, 10> c2 = d2;

2.2赋值

​ 赋值就是把左边容器的元素全部换成右边容器中元素的拷贝。只有顺序容器可以使用assign,但是array不支持assign操作

image-20230307213436479

assign

​ 赋值运算符要求等号两边的运算对象具有相同的类型,assign允许从一个不同但相容的类型赋值,或者从容器的一个子序列赋值。使用assign会使左边容器内部的迭代器、引用和指针失效

swap

swap交换两个相同类型容器的内容,除string外,指向容器的迭代器、引用和指针在swap操作之后都不会失效。swap两个array会正在交换它们的元素

三、顺序容器操作

3.1添加元素

​ 除了array,所有标准库容器都提供灵活的内存管理。下表是添加元素的的操作。前面提到,像vector、string等容器添加一个元素可能会导致整个对象的存储空间重新分配,所以当我们使用这些操作时,必须记得不同容器使用不同的策略来分配元素空间。

image-20230309192600649

当我们将一个对象插入到容器时,实际上放入的是对象的拷贝,容器的元素与提供值的对象之间没有任何关联。

emplace

C++11引入了三个新成员:emplace_front、emplace、emplace_back,前面说了以前的插入元素的方法是拷贝,而这些新成员会进行构造,不会拷贝。下面一段代码很容易理解它们之间的差别。加入有一个info对象,它含有三个数据成员,且对应的构造函数。在使用emplace_back,我们可以在A的末尾添加一个Info对象,但是push_back却不行,因为它是拷贝元素,对于push_back的函数设计里面没有接收三个参数的版本,所以只能写成最后一行的形式,先构造,再拷贝。总之,emplace_back直接进行构造简化了操作过程。当然,如果Info对象没有对应三个参数的构造函数,那么该操作也会失效

A.emplace_back("heyun",12,23);
A.push_back("heyun",12,23); // 错误
A.push_back(Info("heyun",12,23));

3.2删除元素

​ 下标是删除元素的操作。

image-20230309195451698

3.3forward_list

​ 有C语言基础的应该都记得链表,forward_list其实就是一个单向链表。它的特殊之处在于,进行添加和删除元素时,删除或添加的元素之前的那个元素的后继会发生改变。

image-20230309195942688

下表是forward_list特有的插入和删除元素操作。

image-20230309201352502

3.4容器操作使迭代器失效

添加元素

  1. vector和string,如果存储空间被重新分配,指向容器的迭代器、指针和引用都会失效。如果没有重新分配,则指向插入元素之间的有效,之后的全部失效。
  2. deque,除了在首尾之外的任何位置插入元素会让它们都失效,如果在首尾添加元素,迭代器会失效,但指向存在的元素的引用和指针不会失效
  3. list和forward_list,全部都有效

删除元素

  1. list和forward_list,指向容器其他位置的迭代器全部都有效
  2. deque,在首尾之外的任何位置删除元素,指向被删除元素之外其他元素的迭代器、引用或指针也会失效。如果删除的是尾元素,则尾后迭代器也会失效,但是其他迭代器、引用和指针不受影响。如果删除首元素,这些都不受影响
  3. vector和string,指向被删除元素之前的有效。
  4. 只要删除元素,尾后迭代器总是失效。

四、vector对象是如何增长的

​ 第一次接触vector时,就很好奇这个和数组类似的存储容器居然有和链表一样的动态增加容量的功能。我们知道vector为了支持快速随机访问,里面的元素是连续存储的,如果这时vector的空间不足以接纳新的元素,可以再开辟一段连续的空间,就旧元素和新元素一起拷贝进去,最后删除旧的空间。这样虽然能够达到目的,但是经常进行性能会非常之慢。

C++标准库为了避免这种代价,设法减少容器空间重新分配次数的策略。当不得不获取新的内存空间时,vector和string的实现通常会分配比新的空间需求更大的内存空间

​ 我们可以人为的去管理容量的成员函数。对于reserve,只有当前需要的内存空间超过当前容量时才会改变vector的容量。

image-20230309204255024

五、string操作

​ 这一小节主要对第三章的string内容进行一个补充。

5.1构造string 的其他方法

image-20230309211748753

5.2改变string的其他方法

string类型同样支持顺序容器的赋值运算符及assign、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.insert(s.size(), cp + 7); // s == "Stately, plump Buck"


image-20230309213033023

image-20230309213602962

assign总是替换string中的所有内容,append总是将新字符追加到string末尾

5.3string搜索操作

string类提供了6个不同的搜索函数,每个函数都有4个重载版本,如下表所示。每个搜索操作会返回一个string::size_type值,表示匹配发生位置的下标,如果搜索失败,会返回一个名为string::nposstatic成员。两个搜索操作的返回值类型都是一个unsigned类型,所以不要用带符号类型进行接收。

image-20230309213642657

image-20230309213650936

下面写几个书上的例子:

string name("AnnaBelle");
auto pos1 = name.find("Anna"); // pos1 = 0

// 查找给定字符串中任何一个字符匹配的位置
string numbers("0123456789"), name("r2d2");
auto pos = name.find_first_of(numbers);
string dept("1231p23");
auto pos = dept.find_first_not_of(number); // 返回p的下标

5.4compare函数

image-20230309214847872

5.5数值转换

C++11引入多个函数可以实现数值数据与标准库string之间的转换。

image-20230309214921668

六、容器适配器

stack、queue和priority_queue是三个顺序容器适配器。一个适配器是一种机制,能使某种事物的行为看起来像另外一种事物一样。

image-20230309215308928

定义一个适配器

​ 每个适配器都定义两个构造函数:默认构造函数创建一个空对象,接受一个容器的构造函数拷贝该容器来初始化适配器。stack和queue基于deque实现,priority_queue在vector的基础上实现

stack<int> stk(deq); // 从deq拷贝元素到stk
stack<string, vector<string>> str_stk; // 在vector上实现的空栈

所有适配器都要求容器具有添加和删除元素的能力,所以array不适用于适配器。同理forward_list也不行。

stack只要求push_back、pop_back和back,因此可以使用除array和forward_list之外的任何容器类型来构造stack

queue要求back、push_back、front和push_front,因此可以构造于list或deque之上,但不能基于vector构造。

priority_queue除了front、push_back和pop_back操作之外还要求随机访问能力,可以构造于vector或deque之上,不能基于list构造。

栈适配器

image-20230309220158132

队列适配器

priority_queue允许为队列中的元素建立优先级,也就是每个元素含有一个权重,权重大的会优先排在前面。

image-20230309220245287

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/400551.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue3通透教程【六】setup语法糖、computed函数、watch函数

文章目录&#x1f31f; 写在前面&#x1f31f; setup 语法糖&#x1f31f; computed函数&#x1f31f; watch 函数&#x1f31f; 写在最后&#x1f31f; 写在前面 专栏介绍&#xff1a; 凉哥作为 Vue 的忠实 粉丝输出过大量的 Vue 文章&#xff0c;应粉丝要求开始更新 Vue3 的…

体验Linux 块设备驱动实验(模拟块)

目录 一、块设备 二、块设备驱动框架 1、块设备的注册和注销 2、gendisk 结构体 3、block_device_operations 结构体 4、块设备 I/O 请求过程 ①、请求队列 request_queue ②、bio 结构 三、编写驱动之请求队列 1、修改makefile 2、基本的驱动框架​编辑 3、添加头文…

XWiki Annotation Displayer 存在任意代码执行漏洞(CVE-2023-26475)

漏洞描述 XWiki 是一个开源的企业级 Wiki 平台&#xff0c;Annotation Displayer 是 XWiki 中的一个插件&#xff0c;用于在 XWiki 页面上显示注释和其他相关内容。 该项目受影响版本存在任意代码执行漏洞&#xff0c;由于Annotation Displayer 对 Groovy 宏的使用没有限制&a…

机载SAR文献调研(CSDN_0027_20230219)

文献&#xff08;电子所&#xff09;文献名[1]&#xff1a;詹学丽, et al., 一种用于合成孔径雷达的数字去斜方法. 雷达学报, 2015. 4(04): p. 474-480文章摘要该文提出了一种用于合成孔径雷达&#xff08;SAR&#xff09;的数字去斜方法&#xff0c;适用于发射信号脉冲宽度能够…

女神节 | PHP和Java算什么,女工程师才是最美最好的语言!

世界上第一个程序员是女性 第一个发现Bug的也是女性 在智领云有一群追求快乐和独立的女性工程师 她们多有魅力&#xff1f; 工位上她们专注于数据与代码 平日里郊游、瑜伽、插花、科学养娃一件不落 不仅用0和1编织数字世界 也在用心装点自己的生活 今天是国际劳动妇女节…

Linux 虚拟机安装及与windows远程登录

说明&#xff1a; 本次学习是在windows上安装虚拟机进行的。所以需要先安装VMware WorkStation&#xff0c;这玩意需要秘钥。所以你懂的&#xff0c;资源网上很多 Linux镜像文件下载地址CentOS Linux​​​​​​ 一、 打开VMware&#xff0c;点击创建新的虚拟机 二、选择下载…

【FATE联邦学习】自定义数据集自定义神经网络模型下的横向纵向训练

前言 代码大部分来自 https://fate.readthedocs.io/en/latest/tutorial/pipeline/nn_tutorial/Hetero-NN-Customize-Dataset/#example-implement-a-simple-image-datasethttps://fate.readthedocs.io/en/latest/tutorial/pipeline/nn_tutorial/Homo-NN-Customize-your-Datase…

[沧海月明珠有泪]两数求和

自己写的像屎山一样的代码&#xff0c;实在难以入眼。学习下人家优秀的代码思想粗看这个代码&#xff0c;用的是递归的思想前面三行的意思&#xff1a;初始化两个链表。第四行&#xff1a;把两个链表的值相加赋给sum第五行&#xff1a;判断是否大于9第六行&#xff1a;如果l1的…

map 、multimap

目录 1.基本概念,键值对 2.map的构造和赋值 3.map的大小和交换&#xff0c;size,empty,swap 4.map的插入和删除&#xff0c;insert(make_pair),clear,erase,[]利用key访问vale 5.map的查找和统计,find,count 6.map容器的排序&#xff0c;自定义排序&#xff0c;仿函数 6.…

5MW风电永磁直驱发电机-1200V直流并网MATLAB仿真模型

MATLAB2016b运行。主体模型&#xff1a;风机传动模块、PMSG模块、蓄电池模块、超级电容模块、无穷大电源。蓄电池控制、风机控制、逆变器控制。风机输出功率&#xff1a;直流母线电压&#xff1a;逆变器输出电压&#xff1a;逆变器输出电流&#xff1a;混合储能荷电状态&#x…

2023年金三银四跳槽季,阿里巴巴 Java10W 字面经,首次公布

Java 面试 “金三银四”这个字眼对于程序员应该是再熟悉不过的了&#xff0c;每年的金三银四都会有很多程序员找工作、跳槽等一系列的安排。说实话&#xff0c;面试中 7 分靠能力&#xff0c;3 分靠技能&#xff1b;在刚开始的时候介绍项目都是技能中的重中之重&#xff0c;它…

超图iServer扩展开发记录Restlet 1

在“REST 服务发布机制简述”中&#xff0c;讲述了 REST 服务发布的过程&#xff0c;资源的信息保存在资源配置文件里&#xff0c;并通过 REST 应用上下文传递给 REST 应用对象&#xff0c;从而在 HTTP 请求到达 REST 应用对象的时候&#xff0c;能够找到合适的资源实现来处理。…

Jwt简介

目录前言What is JSON Web Token?When should you use JSON Web Tokens?What is the JSON Web Token structure?HeaderPayloadSignaturePutting all togetherHow do JSON Web Tokens work?Why should we use JSON Web Tokens?前言 技术文档这种东西&#xff0c;我一直认为…

数枝营销与纷享销客达成战略合作,共同推动B2B企业营与销一体化

近日&#xff0c;营销咨询与数字化服务商数枝营销同国内知名SaaS CRM厂商纷享销客举行了战略合作签约仪式&#xff0c;双方就促进B2B企业的“营与销协同增长”将展开全面合作。纷享销客创始人兼CEO罗旭与数枝营销创始人黄海钧 另据工商信息显示&#xff0c;数枝营销&#xff08…

webshell管理工具-菜刀的管理操作

什么是webshell Webshell是一种运行在Web服务器上的脚本程序&#xff0c;通常由黑客使用来绕过服务器安全措施和获取对受攻击服务器的控制权。Webshell通常是通过利用Web应用程序中的漏洞或者弱密码等安全问题而被植入到服务器上的。 一旦Webshell被植入到服务器上&#xff0…

基于应用理解的协议栈优化

作者&#xff1a;余兵 移动互联网时代&#xff0c;不同的应用追求的产品体验差异性很大。 应用商店和图片等下载类型业务追求速度、越快越好&#xff0c;短视频关注起播、拖拽响应速度和观看过程卡不卡&#xff0c;直播追求画质清晰、高码率和直播过程流畅&#xff1b;而游戏则…

苹果iPhone屏下Touch ID技术专利获批,苹果Find My技术大火

根据美国商标和专利局&#xff08;USPTO&#xff09;公示的最新清单&#xff0c;苹果近日获得了屏下 Touch ID 的新技术专利。专利中重点提及了“短波红外线”技术&#xff0c;相关元件位于屏幕下方或者集成到屏幕内。 该专利主要介绍了应用于屏幕 Touch ID 的光学成像系统&…

自动化工具selenium(一)

一)什么是自动化&#xff1f;为什么要做自动化&#xff1f; 自动化测试可以代替一部分手工测试&#xff0c;不能够完全代替手工测试 1)自动化测试相比于手工测试来说人力的投入和时间的投入是非常非常少的&#xff0c;自动化测试能够提高测试效率 2)在回归测试里面&#xff0c;…

被隐藏的过程——预处理

文章目录0. 前言1. 程序的翻译环境和执行环境2. 被隐藏的过程2.1 翻译环境2.2 编译3.2.1 预编译3.2.2 编译2.2.3 汇编2.3 链接2.4 运行环境3. 预处理3.1 预定义符号3.2 #define3.2.1 #define定义标识符3.2.2 #define定义宏3.2.3 #define替换规则3.2.4 #和##3.2.5 带副作用的宏参…

API Gateway vs Load Balancer:选择适合你的网络流量管理组件

本文从对比了 API Gateway 和 Load Balancer 的功能区别&#xff0c;帮助读者更好地了解他们在系统架构中扮演的角色。 作者陈泵&#xff0c;API7.ai 技术工程师。 原文链接 由于互联网技术的发展&#xff0c;网络数据的请求数节节攀升&#xff0c;这使得服务器承受的压力越来…