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

C++ 使用动态内存创建一个类

使用动态内存的一个常见原因是允许多个对象共享相同的状态。

例如,假定我们希望定义一个名为Blob 的类,保存一组元素。与容器不同,我们希望Blob对象的不同拷贝之间共享相同的元素。即,当我们拷贝一个Blob时,原Blob对象及其拷贝应该引用相同的底层元素。现在我们先定义一个管理string的类,此版本命名为StrBlob

定义 StrBlob类

实现一个新的集合类型的最简单方法是使用某个标准库容器来管理元素。采用这种方法,我们可以借助标准库类型来管理元素所使用的内存空间。在本例中,我们将使用vector来保存元素。

但是,我们不能在一个Blob对象内直接保存vector,因为一个对象的成员在对象销毁时也会被销毁。例如,

  • 假定b1 b2是两个Blob对象,共享相同的vector
  • 如果此vector保存在其中一个Blob中——例如b2中,那么当b2离开作用域时,此vector也将被销毁,也就是说其中的元素都将不复存在。为了保证 vector中的元素继续存在,我们将vector保存在动态内存中。

为了实现我们所希望的数据共享,我们为每个StrBlob设置一个shared_ptr来管理动态分配的 vector。此 shared_ptr的成员将记录有多少个StrBlob 共享相同的vector,并在vector的最后一个使用者被销毁时释放vector

我们还需要确定这个类应该提供什么操作。当前,我们将实现一个vector操作的小的子集。我们会修改访问元素的操作(如 frontback): 在我们的类中,如果用户试图访问不存在的元素,这些操作会抛出一个异常。

我们的类有一个默认构造函数和一个构造函数,接受单一的 initializer_list<string>类型参数。此构造函数可以接受一个初始化器的花括号列表

initializer_list对象中的元素永远是常量值,我们无法改变initializer_list对象中元素的值。在进行函数调用的时候需要使用花括号将所有的参数括起来。

class StrBlob{
public:typedef std::vector<std::string>::size_type size_type;StrBlob();StrBlob(std::initializer_list<std::string> il);size_type size() const { return data->size(); }bool empty() const { return data->empty(); }//添加和删除元素void push_back(const std::string &t){ data->push_back(t); }void pop_back();//元素访问std::string& front();std::string& back();private:std::shared_ptr<std::vector<std::string>> data;//如果data[i]不合法,抛出一个异常void check(size_type i, const std::string &msg) const;
};

在此类中,我们实现了sizeemptypush_back成员。这些成员通过指向底层vectordata成员来完成它们的工作。例如,对一个 StrBlob对象调用size()会调用data->size(),依此类推。

StrBlob构造函数

两个构造函数都使用初始化列表来初始化其data成员,令它指向一个动态分配的vector。默认构造函数分配一个空vector:

StrBlob::StrBlob() : data(make_shared<vector<string>>()){ }
StrBlob::StrBlob(initializer_list<string> il): data(make_shared<vector<string>>(il)) { }

接受一个initializer_list的构造函数将其参数传递给对应的vector构造函数。此构造函数通过拷贝列表中的值来初始化vector的元素。

元素访问成员函数

pop_backfrontback操作访问vector中的元素。这些操作在试图访问元素之前必须检查元素是否存在。由于这些成员函数需要做相同的检查操作,我们为StrBlob定义了一个名为checkprivate工具函数,它检查一个给定索引是否在合法范围内。除了索引,check还接受一个string参数,它会将此参数传递给异常处理程序,这个string描述了错误内容:

void StrBlob::check(size_type i, const string &msg) const
{if(i >= data->size())throw out_of_range(msg);
}

pop_back元素访问成员函数首先调用check。如果check成功,这些成员函数继续利用底层vector的操作来完成自己的工作:

string& StrBlob::front()
{//如果vector为空,check会抛出一个异常check(0, "front on empty StrBlob");return data->front();
}
string& StrBlob::back()
{check(0, "back on empty StrBlob");return data->back();
}
void StrBlob::pop_back()
{check(0, "pop_back on empty StrBlob");data->pop_back();
}

StrBlob 的拷贝、赋值和销毁

StrBlob使用默认版本的拷贝、赋值和销毁成员函数来对此类型的对象进行这些操作。默认情况下,这些操作拷贝、赋值和销毁类的数据成员。
我们的StrBlob类只有一个数据成员,它是shared_ptr类型。因此,当我们拷贝、赋值或销毁一个 StrBlob对象时,它的shared_ptr成员会被拷贝、赋值或销毁。

  • 拷贝一个shared_ptr会递增其引用计数;
  • 将一个shared_ptr赋予另一个shared_ptr会递增赋值号右侧shared_ptr的引用计数,而递减左侧shared_ptr的引用计数。
  • 如果一个shared_ptr的引用计数变为0,它所指向的对象会被自动销毁。因此,对于由 StrBlob构造函数分配的vector,当最后一个指向它的StrBlob对象被销毁时,它会随之被自动销毁。

注:仅供学习参考,如有不足,欢迎指正!

相关文章:

C++ 使用动态内存创建一个类

使用动态内存的一个常见原因是允许多个对象共享相同的状态。 例如&#xff0c;假定我们希望定义一个名为Blob 的类&#xff0c;保存一组元素。与容器不同&#xff0c;我们希望Blob对象的不同拷贝之间共享相同的元素。即&#xff0c;当我们拷贝一个Blob时&#xff0c;原Blob对象…...

2023年华中杯选题人数公布

2023年华中杯选题人数公布 经过一晚上代码的编写&#xff0c;论文的写作&#xff0c;C题完整版论文已经发布&#xff0c; 注&#xff1a;蓝色字体为说明备注解释字体&#xff0c;不能出现在大家的论文里。黑色字体为论文部分&#xff0c;大家可以根据红色字体的注记进行摘抄。…...

【黑马旅游案例记录(结合ES)】

黑马旅游案例记录 11.9.黑马旅游案例11.9.1.酒店搜索和分页11.9.1.1.需求分析11.9.1.2.定义实体类11.9.1.3.定义controller11.9.1.4.实现搜索业务 11.9.2.酒店结果过滤11.9.2.1.需求分析11.9.2.2.修改实体类11.9.2.3.修改搜索业务 11.9.3.我周边的酒店11.9.3.1.需求分析11.9.3.…...

基于 A* 搜索算法来优化无线传感器节点网络的平均电池寿命(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 A*&#xff08;念做&#xff1a;A Star&#xff09;算法是一种很常用的路径查找和图形遍历算法。它有较好的性能和准确度。本文…...

三款自研AI应用引领未来,重塑行业新风尚

在这个科技日新月异的时代&#xff0c;AI技术已经渗透到我们生活的方方面面。今天&#xff0c;我们将向您推荐三款领域独具特色的AI应用&#xff0c;它们分别是AI律师、AI小红书文案提示词、以及AI Midjourney提示词。这些应用都具有独特的内涵&#xff0c;让我们一起走进这些智…...

Kafka的命令行操作

一、topic命令 下面Windows命令需要把cmd路径切换到bin/windows下。 而Linux命令只需要在控制台切换到bin目录下即可。 下面都以Windows下的操作为例&#xff0c;在Linux下也是一样的。 1.1 查看主题命令的参数 kafka-topics.bat # Windows kafka-topics.sh # Linux输…...

递归,回溯,分治(C++刷题笔记)

递归&#xff0c;回溯&#xff0c;分治&#xff08;C刷题笔记&#xff09; 78. 子集 力扣 预备知识 nums[][1,2,3],先将子集[1],[1,2],[1,2,3]打印 #include <bits/stdc.h>using namespace std;int main() {vector<int>nums;for (int i1;i<3;i){nums.push_…...

CentOS 7.6更改yum源

使用字符串替换 我这里的操作参考了https://baijiahao.baidu.com/s?id1708418392526536542&wfrspider&forpc这篇文章&#xff0c;https://mirrors.tuna.tsinghua.edu.cn/help/centos/是清华大学官网教程。 /etc/yum.repos.d/CentOS-Base.repo文件如下&#xff1a; #…...

三、进度管理

3、 [单选] 一个项目实施团队需要满足一份非常严格的进度计划。相对于已完成的事项&#xff0c;这样会导致正在进行的工作超过负荷。为了解决这个问题&#xff0c;项目经理需要获得额外的资源。项目经理应该向发起人提供什么理由来支持追加资源的请求&#xff1f; A project im…...

基于LEACH和HEED的WSN路由协议研究与改进(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 无线传感器网络是不断发展的传感技术之一&#xff0c;也用于执行不同的任务。这些类型的网络在许多领域都是有益的&#xff0c…...

ChatGPT镜像站收集【Free ChatGPT】(一)

文章目录 Free ChatGPT Site ListLast synced:BeiJingT 2023-04-18妙站站点列表Free ChatGPT Site List 这儿收集了一些免费好用的ChatGPT镜像站点 ⭐:使用不受限🔑:需要进行登录⛔:有限地使用次数后需提供key或进行充值❓ :未测试,未进行标注也为未测试Last synced:BeiJin…...

PHP面试宝典之Mysql数据库基础篇

字符类型&#xff1a; tinyint(4)&#xff1a;占1个字节&#xff0c;4代表字段值长度&#xff0c;用0填充&#xff0c;搭配zero fill使用 有符号&#xff1a;取值范围 负128 &#xff5e; 正127&#xff1b; 无符号&#xff1a;取值范围 0 &#xff5e; 255&#xff1b; 默认无…...

4月记录总结

4/24 1.GBK12、16、24是指什么 GBK12、GBK16、GBK24是指不同的字体点阵大小&#xff0c;也就是字体的显示大小。在GBK编码中&#xff0c;一个汉字通常是由多个点阵组成的&#xff0c;其中点阵的大小就是字体的点阵大小。具体来说&#xff1a; GBK12&#xff1a;指每个汉字由12…...

每日学术速递4.29

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.LG 1.A Cookbook of Self-Supervised Learning 标题&#xff1a;自监督学习食谱 作者&#xff1a;Randall Balestriero, Mark Ibrahim, Vlad Sobal, Ari Morcos, Shashank Shekhar, Tom…...

整数在内存中的存储:原码、反码、补码 大小端字节序

本篇博客会讲解整数在内存中的存储形式&#xff0c;以及整数二进制的3种表示形式&#xff1a;原码、反码、补码&#xff0c;还有大小端的相关知识点。相信读完本篇博客&#xff0c;大家对内存的了解会上一个台阶。 注意&#xff1a;本篇博客讨论的是整数在内存中的存储&#x…...

【方法】 如何批量将RAR或其他压缩格式转换成ZIP?

压缩文件的格式有很多种&#xff0c;比如RAR、ZIP、7-Zip、CAB、ARJ、ACE、TAR、BZ2等等。因为需求不同&#xff0c;或者不同平台对上传的压缩包格式要求不同&#xff0c;我们往往需要把压缩文件进行格式转换&#xff0c;那压缩文件不同格式之间如何进行转换呢&#xff1f; 如…...

《道德经》

《道德经》是春秋时期老子&#xff08;李耳&#xff09;的哲学作品&#xff0c;又称《道德真经》、《老子》、《五千言》、《老子五千文》&#xff0c;是中国古代先秦诸子分家前的一部著作&#xff0c;是道家哲学思想的重要来源。 道德经分上下两篇&#xff0c;原文上篇《德经…...

ABI Research产业研究:ZiFiSense如何革新物流货物及运输包装追踪

“文章源自前沿科技研究机构ABI Research产业研究&#xff0c;重点介绍了ZETA LPWA协议开发公司纵行科技在业务发展、M-FSK调制技术以及ZETag云标签系列产品在物流货物追踪与包装管理等方面的应用分析&#xff0c;还分享了纵行科技ZETA技术在商业市场和生态系统方面的发展情况。…...

家乡特色推荐系统~java~mysql

摘 要 在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括家乡特色推荐的网络应用&#xff0c;在外国家乡特色推荐系统已经是很普遍的方式&#xff0c;不过国内的管理网站可能还处于起步阶段。家乡特色推荐系统采用java技术&…...

二维码在设备点维一体化管理中的应用

随着科技发展&#xff0c;设备点维一体化管理体系应运而生&#xff0c;该管理体系的出现让设备维护保养变得更加高效精细化。 设备点维一体化管理体系以设备点检和维护保养为基础&#xff0c;通过日常、专业及精密点检&#xff0c;对点检测得的数据和设备给油脂保养情况进行统…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...