当前位置: 首页 > news >正文

C++ Primer Plus----第十二章--类和动态内存分布

本章内容包括:对类成员使用动态内存分配;隐式和显式复制构造函数;隐式和显式重载赋值运算符;在构造函数中使用new所必须完成的工作;使用静态类成员;将定位new运算符用于对象;使用指向对象的指针;实现队列抽象数据类型(ADT)。

12.1 动态内存和类

C++在分配内存时采取的策略是让程序在运行时决定内存分配,而不是在编译时再做决定。C++使用new和delete运算符来动态控制内存。遗憾的是,在类中使用这些运算符就会出现许多新的编程问题。在这种情况下,析构函数将是必不可少的。

  1. 让程序在运行时决定内存分配,而不是在编译时决定。
  2. C++使用new和delete运算符来动态控制内存,在类中使用这些运算符,析构函数将是必不可少的。
  3. 类对象定义的字符串并不保存在对象中。字符串单独保存在堆内存中,对象仅保存了指出到哪里去查找字符串的信息。
  4. 在构造函数中使用new来分配内存时,必须在相应的析构函数中使用delete来释放内存。如果使用new[](包括中括号)来分配内存,则应使用delete[](包括中括号)来释放内存。
12.1.1 复习示例和静态类成员

程序清单12.1,12.2,12.3;一个不完整的类,类方法实现,演示了StringBad类的构造函数和析构函数何时运行以及如何运行的; · d1e76f9 · Kite/C和C++ - Gitee.com

 上述代码需要注意的有两点,私有成员中使用了char指针,而不是char数组来表示姓名。这意味着类声明没有为字符串本身分配存储空间,而是在构造函数中使用new来为字符串分配空间。这避免了在类声明中预先定义字符串的长度。

其次,将num_strings成员声明为静态存储类。静态存储类有一个特点:无论创建了多少对象,程序都只创建一个静态类变量副本

 下面解释一下程序清单12.2,

int StringBad::num_strings = 0;// 初始化静态变量,用于记录创建的类数量

        不能在类声明中初始化静态成员变量,这是因为声明描述了如何分配内存,但并不分配内存。

        对于静态类成员,可以在类声明之外使用单独的语句来进行初始化,这是因为静态类成员是单独存储的,而不是对象的组成部分。

        注意,初始化部分指出了类型,并使用了作用域运算符,但是没有使用关键字static。

        静态数据成员在类声明中声明,在包含类方法的文件中初始化。初始化时使用作用域运算符来指出静态成员所属的类。但如果静态成员是const整数类型或枚举型,则可以在类声明中初始化。

        说明一下为什么不要在类声明中初始化,这是因为类声明位于头文件中,这个头文件可能在多个文件中引用,那么就会出现多个初始化语句副本,也就是重复了,就会引发错误。

StringBad::StringBad(const char * s)
{// str = s;             // 这只保存了地址,而没有创建字符串副本。len = std::strlen(s);   // 不包括末尾的空字符str = new char[len+1];  // 使用new分配足够的空间来保存字符串,然后将新内存的地址赋给str成员。std::strcpy(str, s);num_strings++;cout << num_strings << " : \"" << str << "\" object created.\n";
}String boston(“Boston”);//可以这么用,字符串就是地址

         看一下这个非默认构造函数,首先strlen()计算字符串的长度,但不包括末尾的空字符,所以需要将len+1。

        strcpy()函数是将后者复制到前者。

        这种方法,字符串并不保存在对象中,字符串单独保存在堆内存中。

        最后析构函数,当对象过期时,str指针也将过期。但str指向的内存仍被分配,除非使用delete释放。删除对象可以释放对象本身占用的内存,但并不能自动释放属于对象成员的指针指向的内存。因此,必须要使用析构函数。在析构函数中使用delete语句可确保对象过期时,由构造函数使用new分配的内存被释放。

        由于缺陷比较多,所以可能运行输出结果是不确定的。输出中出现的各种非标准字符随系统而异。

         程序执行到这里应该还是没有问题的(也许只是看起来);

 callme1(headline1);

        当执行到这里就会出现明显的错误了,callme2()按值(而不是按引用)传递headline2。

callme2(headline2); // 复制构造函数被用来初始化 callme2()的形参

 

相关文章:

C++ Primer Plus----第十二章--类和动态内存分布

本章内容包括&#xff1a;对类成员使用动态内存分配&#xff1b;隐式和显式复制构造函数&#xff1b;隐式和显式重载赋值运算符&#xff1b;在构造函数中使用new所必须完成的工作&#xff1b;使用静态类成员&#xff1b;将定位new运算符用于对象&#xff1b;使用指向对象的指针…...

清理 Oracle Arch 目录中的日志文件

清理Oracle Arch目录中的文件需要遵循以下步骤&#xff1a; 1、登陆Oracle数据库服务器&#xff1a;确保你有权限访问Oracle数据库服务器&#xff0c;并且能够登录到服务器操作系统。 ssh 192.168.1.200 su - oracle2、启动RMAN&#xff08;Recovery Manager&#xff09;&…...

PicGo+GitHub搭建免费图床

PicGoGitHub搭建免费图床 步骤 1: 安装 PicGo步骤 2:创建图床仓库步骤 3: 配置 GitHub Token步骤 4: 配置 PicGo步骤 5: 上传图片步骤 6: 访问图片 使用 GitHub 作为图床的优势在于免费、稳定且具有版本控制功能&#xff0c;特别适合个人博客、小型项目等。PicGo作为一个开源的…...

免费在线客服软件推荐:经济实用的客户沟通解决方案

好用的在线客服软件是企业是必不可少的工具&#xff0c;他让企业流程更流畅高效&#xff0c;让客户服务更完善优质。市场上的在线客服软件有很多&#xff0c;说着免费使用的软件也不在少数。今天小编就来推荐一款免费在线客服软件。 不过&#xff0c;我们选择免费在线客服软件…...

leetcode344. 反转字符串

题目描述 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 示例 1&#xff1a; 输入&#xff1a;s ["h&quo…...

【js自定义鼠标样式】【js自定义鼠标动画】

文章目录 前言一、效果图二、实现步骤1. 去除原有鼠标样式2. 自定义鼠标样式3. 使用 总结 前言 自定义鼠标形状&#xff0c;自定义鼠标的动画&#xff0c;可以让我们的页面更加有设计感。 当前需求&#xff1a;吧鼠标自定义成一个正方形&#xff0c;鼠标的效果有&#xff1a;和…...

Linux开发工具——gdb篇

Linux下调试工具——gdb 文章目录 makefile自动化构建工具 gdb背景 gdb的使用 常用命令 总结 前言&#xff1a; 编写代码我们使用vim&#xff0c;编译代码我们使用gcc/g&#xff0c;但是我们&#xff0c;不能保证代码没问题&#xff0c;所以调试是必不可少的。与gcc/vim一样&…...

spring状态机

1、概述 Spring State Machine 是一个用于处理状态机逻辑的框架&#xff0c;它提供了一种简洁的方法来定义状 态、转换以及在状态变更时触发的动作。 概念 状态 &#xff08; State &#xff09; &#xff1a;一个状态机至少要包含两个状态。例如自动门的例子&#xff0c;有 …...

K8S异常处理

一、概述 1、k8s有时候会报错The connection to the server ip:6443 was refused - did you specify the right host or port &#xff0c;本文档提供几种可能产生该报错的原因和排障思路。 二、发现问题 使用任意Kubectl 命令会报错&#xff1a;The connection to the serv…...

【挑战全网最易懂】深度强化学习 --- 零基础指南

深度强化学习介绍、概念 强化学习介绍离散场景&#xff0c;使用行为价值方法连续场景&#xff0c;使用概率分布方法实时反馈连续场景&#xff1a;使用概率分布 行为价值方法 强化学习六要素设计奖励函数设计评论家策略学习与优化 算法路径深度 Q 网络 DQN演员-评论家算法&…...

WPF RelativeSource

RelativeSource 类在 WPF 中提供了以下几种模式&#xff1a; RelativeSource Self&#xff1a;指定当前元素作为相对源。可以在当前元素的属性中绑定到自身的属性。 示例&#xff1a; <TextBlock Text"{Binding Text, RelativeSource{RelativeSource Self}}" /&…...

centos 安装 配置 zsh

centos 编译安装 zsh 和 配置 oh-my-zsh 下载 wget https://jaist.dl.sourceforge.net/project/zsh/zsh/5.9/zsh-5.9.tar.xz依赖 yum install ncurses-devel安装zsh 执行&#xff1a; tar -xvf zsh-5.9.tar.xz cd zsh-5.9 ./configure --prefix/usr/local/zsh5.9 make &am…...

git 常用基本命令, reset 回退撤销commit,解决gitignore无效,忽略记录或未记录远程仓库的文件,删除远程仓库文件

git 基本命令 reset 撤销commit https://blog.csdn.net/a704397849/article/details/135220091 idea 中 rest 撤销commit过程如下&#xff1a; Git -> Rest Head… 在To Commit中的HEAD后面加上^&#xff0c;点击Reset即可撤回最近一次的尚未push的commit Reset Type 有三…...

Vue Echarts 多折线图只有一条X轴(合并X轴数据并去重排序) - 附完整示例

echarts&#xff1a;一个基于 JavaScript 的开源可视化图表库。 目录 效果 一、介绍 1、官方文档&#xff1a;Apache ECharts 2、官方示例 二、准备工作 1、安装依赖包 2、示例版本 三、使用步骤 1、在单页面引入 echarts 2、指定容器并设置容器宽高 3、数据处理&am…...

WPF+Halcon 培训项目实战(6):目标匹配助手

文章目录 前言相关链接项目专栏模板匹配助手简单使用金字塔级别参数自动选择应用插入代码 总结 前言 为了更好地去学习WPFHalcon&#xff0c;我决定去报个班学一下。原因无非是想换个工作。相关的教学视频来源于下方的Up主的提供的教程。这里只做笔记分享&#xff0c;想要源码…...

Linux管理LVM逻辑卷

目录 一、LVM逻辑卷介绍 1. 概述 2. LVM基本术语 2.1 PV&#xff08;Physical Volume&#xff0c;物理卷&#xff09; 2.2 VG (Volume Group&#xff0c;卷组&#xff09; 2.3 LV (Logical Volume&#xff0c;逻辑卷&#xff09; 3. 常用的磁盘命令 4. 查看系统信息的命…...

vue如何实现局部刷新?

应用场景&#xff1a; 比如你要切换tap栏实现刷新下面form表单等&#xff0c;相当于刷新页面。 如何使用如下&#xff1a; <div v-if"isReloadData"> 比如你想刷新那个位置就把 v-if"isReloadData"写到那个标签上 </div> 在data中定义刷新标…...

C语言,指针链表详解解说及代码示例

C语言&#xff0c;指针链表详解解说及代码示例 指针链表是一种常用的数据结构&#xff0c;用于存储和组织数据。它由一系列节点组成&#xff0c;每个节点包含数据和一个指向下一个节点的指针。通过这种方式&#xff0c;可以动态地添加、删除和访问节点&#xff0c;实现灵活的数…...

6、LLaVA

简介 LLaVA官网 LLaVA使用Vicuna(LLaMA-2)作为LLM f ϕ ( ⋅ ) f_\phi() fϕ​(⋅)&#xff0c;使用预训练的CLIP图像编码器 ViT-L/14 g ( X v ) g(X_v) g(Xv​)。 输入图像 X v X_v Xv​&#xff0c;首先获取feature Z v g ( X v ) Z_vg(X_v) Zv​g(Xv​)。考虑到最后一…...

SpringMVC核心处理流程梳理

1、处理流程图展示 当我拿出这张图&#xff0c;阁下又该如何应对呢&#xff1f;执行流程是不是一目了然了。【记住一句话&#xff1a;所有的注解都只是一个标签或者标记&#xff0c;最终都是反射找到具体方法上面的注解标记&#xff0c;然后找到类、属性、方法扩展自己想要的功…...

通义千问2.5-7B-Instruct开发者指南:API调用代码实例详解

通义千问2.5-7B-Instruct开发者指南&#xff1a;API调用代码实例详解 1. 快速了解通义千问2.5-7B-Instruct 通义千问2.5-7B-Instruct是阿里云在2024年9月发布的70亿参数指令微调模型&#xff0c;属于中等体量的全能型AI助手&#xff0c;最大的特点是完全开源且可以商用。 这…...

cv_resnet50_face-reconstruction效果对比:不同光照/姿态下人脸重建质量实测报告

cv_resnet50_face-reconstruction效果对比&#xff1a;不同光照/姿态下人脸重建质量实测报告 你是不是也好奇&#xff0c;一个基于ResNet50的人脸重建模型&#xff0c;到底能把一张照片还原到什么程度&#xff1f;它能不能处理好那些光线不好、角度刁钻的照片&#xff1f;今天…...

Keil工程管理效率翻倍:Python脚本实现构建结果自动归档与HTML报告生成

Keil工程管理效率翻倍&#xff1a;Python脚本实现构建结果自动归档与HTML报告生成 在嵌入式开发领域&#xff0c;Keil作为主流开发工具链的核心组件&#xff0c;其工程管理效率直接影响着团队协作和产品迭代速度。传统开发流程中&#xff0c;工程师往往需要手动收集每次构建生成…...

uniapp日期处理全攻略:获取某月首尾日、近七天日期等实用技巧

Uniapp日期处理实战&#xff1a;从基础格式化到高级业务场景解决方案 在移动应用开发中&#xff0c;日期处理几乎贯穿所有业务场景。无论是电商平台的限时抢购、医疗应用的预约挂号&#xff0c;还是企业系统的报表统计&#xff0c;精准高效的日期操作都是保障业务逻辑完整性的关…...

别再只调PID了!基于STM32C8T6的电磁循迹小车,从硬件滤波到软件算法的抗干扰全攻略

电磁循迹小车的抗干扰实战&#xff1a;从硬件滤波到软件优化的全链路解决方案 当你的电磁循迹小车在实验室里跑得风生水起&#xff0c;一到比赛现场却频频"抽风"&#xff0c;这往往不是PID参数调得不够好&#xff0c;而是整个系统的抗干扰设计存在漏洞。本文将带你深…...

告别重复代码:BaseMapperPlus在SpringBoot项目中的5个高级用法

BaseMapperPlus实战&#xff1a;SpringBoot项目中提升开发效率的5个高阶技巧 在SpringBoot项目中使用MyBatis-Plus进行数据持久层开发时&#xff0c;BaseMapperPlus作为社区广泛采用的扩展接口&#xff0c;能显著减少模板代码。本文将分享五个实际业务场景中的高阶用法&#xf…...

鸿蒙SpeechKit离线语音识别避坑指南:从PCM格式到权限配置,一次搞定

鸿蒙SpeechKit离线语音识别实战避坑指南 1. 音频格式的致命陷阱 PCM格式是鸿蒙SpeechKit离线语音识别的唯一选择&#xff0c;但开发者常犯的错误远不止文件类型这么简单。我曾见过一个团队花费三天时间排查识别率低的问题&#xff0c;最终发现是采样深度设置错误——这个细节在…...

陀螺匠企业助手-产品

1. 功能说明维护出售产品的基本信息数据&#xff0c;支持在添加商机/合同中进行选择。2. 进入产品页面路径&#xff1a;客户>产品管理>产品3. 新增产品功能说明&#xff1a;维护产品信息&#xff0c;添加完成的产品信息&#xff0c;可以在添加商机/合同中进行选择。新增产…...

GaussDB JDBC SSL加密全攻略:从零配置到生产环境最佳实践

GaussDB JDBC SSL加密全攻略&#xff1a;从零配置到生产环境最佳实践 在数据驱动的时代&#xff0c;数据库连接的安全性已成为企业级应用不可忽视的生命线。作为华为云推出的分布式关系型数据库&#xff0c;GaussDB在金融、政务等对安全性要求极高的场景中广泛应用。而JDBC作为…...

别再让PowerBI报告挤成一团了!用按钮+书签,一个页面搞定趋势和明细分析

PowerBI交互设计进阶&#xff1a;用按钮与书签打造空间魔术 当业务分析报告遇上数据爆炸时代&#xff0c;信息过载与界面拥挤成为每个分析师挥之不去的噩梦。我曾见过某零售企业的季度分析仪表板——12个图表密密麻麻挤在A4纸大小的画布上&#xff0c;趋势线相互缠绕&#xff…...