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

目录

第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.hqwc.cn/news/59346.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python机器学习】实验08 决策树

文章目录 决策树1 创建数据2 定义香农信息熵3 条件熵4 信息增益5 计算所有特征的信息增益&#xff0c;选择最优最大信息增益的特征返回6 利用ID3算法生成决策树7 利用数据构造一颗决策树Scikit-learn实例决策树分类决策树回归Scikit-learn 的决策树参数决策树调参 实验1 通过sk…

数据请求与导入mysql数据库

端口数据获取与文件保存 文件存入数据库 系统&#xff1a;Ubuntu 工具&#xff1a;Postman&#xff0c;MySql Workbench 端口数据获取与文件保存 打开postman接口测试工具 选择请求方式输入请求地址选择请求参数设置请求参数的格式输入请求参数发送请求 请求成功 选择浏览…

Jmeter-获取接口响应头(Response headers)信息进行关联

文章目录 Jmeter-获取接口响应头&#xff08;Response headers&#xff09;信息进行关联使用正则表达式提取器将Set-Cookie的值提取出来在其余接口中关联该提取信息运行查看关联是否成功 Jmeter-获取接口响应头&#xff08;Response headers&#xff09;信息进行关联 获取某一…

学习电气工程的关键要点

基础知识&#xff1a;学习电路原理、电子器件、电机原理等基础知识。可以通过自学、培训或相关专业课程来学习。 编程技能&#xff1a;掌握一门编程语言&#xff0c;如C语言或MATLAB。电气工程常需要编程来设计和实现控制系统。 自动化控制理论&#xff1a;了解自动化控制系…

【IDEA+Spark Streaming 3.4.1+Dstream监控套接字流统计WordCount保存至MySQL8】

【IDEASpark Streaming 3.4.1Dstream监控套接字流统计WordCount保存至MySQL8】 把DStream写入到MySQL数据库中 Spark 3.4.1MySQL 8.0.30sbt 1.9.2 文章目录 【IDEASpark Streaming 3.4.1Dstream监控套接字流统计WordCount保存至MySQL8】前言一、背景说明二、使用步骤1.引入库2…

Add-in Express for Microsoft Office and Delphi Crack

Add-in Express for Microsoft Office and Delphi Crack 适用于Microsoft Office和Delphi VCL的Add-in Express使您能够在几次点击中为Microsoft Office开发专业插件。它生成基于COM的项目&#xff0c;这些项目包含Microsoft Office外接程序或智能标记的所有必要功能&#xff0…

IT 基础架构自动化

什么是 IT 基础架构自动化 IT 基础架构自动化是通过使用技术来控制和管理构成 IT 基础架构的软件、硬件、存储和其他网络组件来减少人为干预的过程&#xff0c;目标是构建高效、可靠的 IT 环境。 为什么要自动化 IT 基础架构 为客户和员工提供无缝的数字体验已成为企业的当务…

《合成孔径雷达成像算法与实现》Figure3.9

代码复现如下&#xff1a; clc clear close all% 参数设置 TBP 100; % 时间带宽积 T 7.2e-6; % 脉冲持续时间 t_0 1e-6; % 脉冲回波时延% 参数计算 B TBP/T; …

利用Google Docs的评论功能投递钓鱼链接

情报背景 利用Google drive等可信云服务进行的网络钓鱼攻击活动日益增长&#xff0c;这种攻击手段利用了高可信度的云服务骗取受害者的信任&#xff0c;并且可以绕过基于域名的安全策略。 近期Avanan公司发现了一种新的邮件钓鱼方式&#xff0c;攻击者利用Google docs的评论功…

语音信号的A律压缩和u律压缩matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 A律压缩算法 4.2 μ律压缩算法 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 clc; clear; close all; warning off; addpath(genpath(…

DP-GAN剩余代码

在前面计算完损失后&#xff0c;该进行更新&#xff1a; 1&#xff1a;netEMA是模型的生成器&#xff1a; 遍历生成器的state_dict&#xff0c;将每一个键对应的值乘以EMA_decay。 接着根据当前迭代步数计算num_upd&#xff0c;每1000,2500,10000代倍数就执行一次。 当num…

HCIA---TCP/UDP协议

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 目录 文章目录 一.UDP协议简介 UDP协议的特点&#xff1a; 二.TCP协议简介 TCP协议特点 三.TCP和UDP的区别 四.TCP/IP结构详解 五.TCP运输连接的阶段 ​编…