C++ Primer(第5版) 全书重点学习笔记

news2024/11/16 7:39:55

目录

第12章 动态内存

12.1 动态内存与智能指针

12.1.6 weak_ptr

12.2 动态数组

12.2.1 new和数组

12.2.2  allocator类


 

第12章 动态内存

12.1 动态内存与智能指针

12.1.6 weak_ptr

weak_ptr是一种不控制所指向对象生存期的智能指针,它指向由一个shared_ptr管理的对象。将一个weak ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放。

当我们创建一个weak ptr时,要用一个shared ptr来初始化它:

auto p = make_shared<int>(42);
weak_ptr<int> wp(p);

由于对象可能不存在,我们不能使用weak_ptr直接访问对象,而必须调用lock检查weak_ptr指向的对象是否仍存在。如果存在,lock返回一个指向共享对象的shared ptr。

if (shared_ptr<int> np = wp.lock()) { 
    // 只有当1ock调用返回true时我们才会进入if语句体
}

12.2 动态数组

12.2.1 new和数组

为了让new分配一个对象数组,我们要在类型名之后跟一对方括号,在其中指明要分配的对象的数目。方括号中的大小必须是整型,但不必是常量。

//调用get size确定分配多少个int
int *pia = new int[get size()]; //pia指向第一个int

也可以用一个表示数组类型的类型别名来分配一个数组,这样,new表达式中就不需要方括号了:

typedef int arrT[42];    //arrT表示42个int的数组类型
int *p = new arrT;    //分配一个42个int的数组;p指向第一个int
int *p = new int[42];   //编译器执行这个表达式时还是会用new[]

 typedef用法:【C/C++】中【typedef】用法大全_c++中typedef的用法

当用new分配一个数组时,我们并未得到一个数组类型的对象,而是得到一个数组元素类型的指针。即使我们使用类型别名定义了一个数组类型,new也不会分配一个数组类型的对象。在上例中,new返回的是一个元素类型的指针。
由于分配的内存并不是一个数组类型,因此不能对动态数组调用begin或end。这些函数使用数组维度来返回指向首元素和尾后元素的指针。出于相同的原因,也不能用范围for语句来处理动态数组中的元素。

初始化动态分配对象的数组:默认情况下,new分配的对象,不管是单个分配的还是数组中的,都是默认初始化的。可以对数组中的元素进行值初始化方法是在大小之后跟一对空括号。在新标准中,我们还可以提供一个元素初始化器的花括号列表。

int* pia = new int[10];    //10个未初始化的int
int* pia2 = new int[10]();   //10个值初始化为0的int       
    
int* pia3 = new int[10]{ 0,1,2,3,4,5,6,7,8,9 };   //10个1nt分别用列表中对应的初始化器初始化
string* pia4 = new string[10]{ "a","an","the",string(3,'x') };   //10个string,前4个用给定的初始化器初始化,剩余的进行值初始化

动态分配一个空数组是合法的:当我们用new分配一个大小为0的数组时,new返回一个合法的非空指针,但此指针不能解引用一毕竟它不指向任何元素。

char arr[0];     // 错误:不能定义长度为0的数组
char* cp = new char[0];      //正确:但cp不能解引用

释放动态数组:为了释放动态数组,我们使用一种特殊形式的delete一在指针前加上一个空方括号对。当我们释放一个指向数组的指针时,空方括号对是必需的:它指示编译器此指针指向一个对象数组的第一个元素。如果我们在delete一个指向数组的指针时忽略了方括号其行为是未定义的。

delete cp;    // p必须指向一个动态分配的对象或为空
delete [] cp;    //pa必须指向一个动态分配的数组或为空

智能指针和动态数组:标准库提供了一个可以管理new分配的数组的unique_ptr版本。为了用一个
unique_ptr管理动态数组,我们必须在对象类型后面跟一对空方括号。

当一个unique ptr指向一个数组时,我们不能使用点和箭头成员运算符。毕竟unique ptr指向的是一个数组而不是单个对象,因此这些运算符是无意义的。当一个unique ptr指向一个数组时,我们可以使用下标运算符来访问数组中的元素。

// up指向一个包含10个未初始化int的数组	
unique_ptr<int[]> up(new int[10]);
for (size_t i = 0; i != 10; ++i) {
	up[i] = i;
	cout << "up" << "[" << i << "]:" << up[i] << endl;
}
//自动用delete[]销毁其指针
up.release();

与unique_ptr不同,shared_ptr不直接支持管理动态数组。如果希望使用shared_ptr管理一个动态数组,必须提供自己定义的删除器。

shared_ptr未定义下标运算符,而且智能指针类型不支持指针算术运算。因此,为了访问数组中的元素,必须用get获取一个内置指针,然后用它来访问数组元素。

 

12.2.2  allocator类

allocator类:标准库allocator类定义在头文件memory中,它帮助我们将内存分配和对象构造分离开来。它提供一种类型感知的内存分配方法,它分配的内存是原始的、未构造的。

为了定义一个allocator对象,我们必须指明这个allocator可以分配的对象类型。当一个allocator对象分配内存时,它会根据给定的对象类型来确定恰当的内存大小和对齐位置。

allocator<string> alloc;    //可以分配string的allocator对象
auto const p = alloc.allocate(8);    //分配n个未初始化的string

allocator分配未构造的内存:allocator分配的内存是未构造的(unconstructed)。我们按需要在此内存中构造对象。在新标准库中,construct成员函数接受一个指针和零个或多个额外参数,在给定
位置构造一个元素。

auto q = p;    // q指向最后构造的元素之后的位置
alloc.construct(q++);    //*q为空字符串
alloc.construct(q++, 10, 'c');    //*q为cccccccccc
alloc.construct(q++, "hi");    //*g为hi!

为了使用allocate返回的内存,我们必须用construct构造对象。使用未构造的内存,其行为是未定义的。

当我们用完对象后,必须对每个构造的元素调用destroy来销毁它们。函数destroy接受一个指针,对指向的对象执行析构函数:

while(q!=p)
    alloc.destroy(--q);  //释放我们真正构造的string

在循环开始处,q指向最后构造的元素之后的位置。我们在调用destroy之前对q进行了递减操作。因此,第一次调用destroy时,q指向最后一个构造的元素。最后一步循环中我们destroy了第一个构造的元素,随后g将与p相等,循环结束。 

释放内存通过调用deallocate来完成

alloc.deallocate(p, n);

拷贝和填充未初始化内存的算法 :标准库还为allocator类定义了两个伴随算法,可以在未初始化内存中创建对象,它们都定义在头文件memory中。

uninitialized_copy(b,e,b2)从迭代器b和e指出的输入范围中拷贝元素到迭代器b2指定的未构造的原始内存中。b2指向的内存必须足够大,能容纳输入序列中元素的拷贝
uninitialized_copy_n(b,n,b2)从迭代器b指向的元素开始,拷贝n个元素到b2开始的内存中
uninitialized_fill(b,e,t)在迭代器b和e指定的原始内存范围中创建对象,对象的值均为t的拷贝
uninitialized_fill_n(b,n,t)从迭代器b指向的内存地址开始创建n个对象。b必须指向足够大的未构造的原始内存,能够容纳给定数量的对象

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

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

相关文章

微信小程序申请步骤

微信公众平台链接&#xff1a;https://mp.weixin.qq.com/ 1、进到微信公众平台&#xff0c;点一下“点击注册”&#xff0c;挑选账号申请种类“小程序”&#xff0c;填好微信小程序用户信息&#xff0c;包含电子邮箱、登陆密码等。 2、微信公众平台会发送一封电子邮件&#xf…

监控Elasticsearch的关键指标

Elasticsearch 的核心职能就是对外提供搜索服务&#xff0c;所以搜索请求的吞吐和延迟是非常关键的&#xff0c;搜索是靠底层的索引实现的&#xff0c;所以索引的性能指标也非常关键&#xff0c;Elasticsearch 由一个或多个节点组成集群&#xff0c;集群自身是否健康也是需要我…

Linux网络服务之SSH

SSH 一、SSH概述1.1 定义1.2 SSH的优点1.3 OpenSSH1.3.1 定义1.3.2 SSH服务器-----sshd 二、SSH原理三、SSH登录方式3.1 方式一3.2 方式二3.3 方式三&#xff1a;跳板连接3.3.1 跳板连接概述3.3.2 具体配置 3.4 方式四&#xff1a;远程控制 四、服务端配置4.1 系统安全架构----…

企业内部wiki,让知识不再流于表面,让企业管理更加高效

企业内部wiki是一种基于wiki技术的内部知识管理平台&#xff0c;通常由企业自行搭建和维护&#xff0c;用于收集和整理企业内部的知识、经验和流程等信息。它可以帮助企业实现知识共享、协作和沟通&#xff0c;提高工作效率和团队协作能力。企业内部wiki还可以作为企业文化建设…

Python Pandas 使用示例

文章目录 使用Boolean 选择rows读取Excel表格里指定的sheet, 并跳过起始n行删除只有一个元素的行删除重复的合并多个csv文件到excel表格中获取csv文件的数据 使用Boolean 选择rows import pandas as pd# Sample DataFrame data {Name: [John, Alice, Bob, Emily],Age: [25, 3…

Segment Anything(SAM) 计算过程

给定输入图像 I ∈ R 3 H W I \in R^{3 \times H \times W} I∈R3HW。给定需要的prompts&#xff1a; M ∈ R 1 H W M \in R^{1 \times H \times W} M∈R1HW&#xff0c;代表图片的前背景信息。 P ∈ R N 2 P \in R^{N \times 2} P∈RN2&#xff0c;其中 N N N 是点的个数…

SpringBoot 底层机制分析【Tomcat 启动+Spring 容器初始化+Tomcat 如何关联Spring 容器】【下】

&#x1f600;前言 本篇博文是关于SpringBoot 底层机制分析实现&#xff0c;希望能够帮助你更好的了解SpringBoot &#x1f60a; &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大…

多年软件测试面试经验,给正在面试工作的一些建议

工作8年多&#xff0c;测试管理经验4年左右&#xff0c;电话面试现场面试了很多测试工程师候选人员&#xff0c;总结下面试过程中我经常会问到的问题和梳理下我的面试流程&#xff0c;希望对候选人员有所帮助。 1.自我介绍 自我介绍其实并不是我想了解除了简历之外的候选人的…

【王树森】深度强化学习(DRL)课程笔记:P2 价值学习

Value-Based RL 试图找出能预测最优action的Q*函数 Deep Q Network(DQN) Temporal Difference(TD) Learning Example 如果在只到半路DC能不能更新模型&#xff1f; TD在这种情况下也可以学习的原因 TD learning for DQN 使用TD Learning 训练 DQN Summary

oracle sql developer批量删除某个用户

随着navicate收费&#xff0c;还得破解&#xff0c;pl/sql developer配置麻烦&#xff0c;最近使用oracle sql developer来试试oracle的操作如何&#xff1b; 用着还行&#xff0c;没有卡顿现象&#xff0c; 最近要oracle sql developer批量删除某个用户下所有的表&#xff0…

springboot中消失的静态资源

springboot中消失的静态资源 问题&#xff1a;springboot项目中&#xff0c;resource/static 目录下的index.html以及template目录下 。实现WebMvcConfigurer这个接口&#xff0c;index.html就404了。 原因&#xff1a;实现了 WebMvcConfigurer 接口后&#xff0c;index.html …

网络安全的相关知识点

网络安全威胁类型&#xff1a; 1.窃听&#xff1a;广播式网络系统。 2.假冒 3.重放&#xff1a;重复一份报文或者报文的一部分&#xff0c;以便产生一个被授权的效果。 4.流量分析 5.数据完整性破坏 6.拒绝服务 7.资源的非授权使用 8.陷门和特洛伊木马&#xff1a;木马病毒有客…

Kali中AWD靶机环境搭建

Kali中AWD靶机环境搭建 1、kali安装docker2、克隆项目&#xff08;400多M&#xff0c;下载会有点久&#xff09;3、进入项目4、下载镜像5、改镜像名6、比赛环境搭建6.1 启动靶机6.2 连接裁判机&#xff0c;启动check脚本6.3 关闭环境命令 7、 靶机访问方式7.1 web界面访问7.2 s…

AMD 翻身无望,RX7000多款主流新卡出炉逗乐NVIDIA

看了今年 NVIDIA RTX 40 系中端主流级显卡&#xff0c;让咱明白了什么叫毫无诚意。 4060 核心规模不及 4090 的 19%、4060Ti 打不过 3070&#xff0c;可真是小刀划屁股开了眼。 奈何 AMD 这代 RX 7000 系显卡着实给不上压力。 旗舰 RX 7900 XTX、7900 XT 完全不敌 RTX 4090、…

go get报错

这里写目录标题 执行 go install github.com/mitchellh/goxlatest提示下面错误&#xff0c;我浏览器直接访问时能访问了&#xff0c;这个下面的提示是golang代理问题 go install: github.com/mitchellh/goxlatest: module github.com/mitchellh/gox: Get “https://proxy.golan…

职场演讲口才培训的影响研究:演讲训练项目的效果探究

题目&#xff1a;职场演讲口才培训的影响研究&#xff1a;演讲训练项目的效果探究 I. 引言 A. 话题背景和意义 在现代职场中&#xff0c;良好的演讲口才已经成为一个不可或缺的技能。随着全球化和信息技术的迅速发展&#xff0c;职场中的沟通方式和需求也发生了巨大变化。无论…

多门店小程序怎么弄

连锁多门店小程序是一种基于微信平台的应用&#xff0c;旨在为连锁企业提供线上线下一体化的服务。以下是该小程序的功能介绍&#xff1a; 1. 门店查找&#xff1a;用户可以通过小程序查找附近的连锁门店&#xff0c;根据地理位置、距离等条件进行筛选&#xff0c;并查看每个门…

MFC创建和使用OCX控件

文章目录 MFC建立OCX控件注册OCX控件与反注册使用Internet Explorer测试ocx控件OCX控件添加方法OCX控件添加事件Web使用OCX控件MFC使用OCX控件使用OCX控件调用ocx的功能函数对ocx的事件响应OCX控件调试工具tstcon32.exe加载ocx控件使用tstcon32.exe调试ocxMFC建立OCX控件 新建…

镜像网站汇总【8月9日更新】

今日最新整理&#xff1a;还是最基本原则&#xff1a; 不用注册&#xff0c; 不用登录&#xff0c; 不用魔法&#xff0c; 不用梯子&#xff0c; 必须是上来就用的镜像&#xff01; 第一个&#xff1a;可用网址汇总 网址&#xff1a;https://c.aalib.net/tool/chatgpt/ …

【原创】基于JavaWeb的婚礼策划平台

主要功能介绍&#xff1a;系统基于Java语言开发。整个程序属于B/S架构应用。在开发的时候&#xff0c;将婚礼策划中主要的业务如&#xff1a;婚纱摄影预约以及婚纱租赁等作为主要的目标和研究方向。婚礼策划平台系统从整体结构设计上&#xff0c;由网站前台和系统后台组成。网站…