每日学习记录003:(C++)unique_ptr和shared_ptr

每日学习记录003:(C++)unique_ptr和shared_ptr

在C++中,unique_ptr和shared_ptr都是智能指针,它们为动态内存管理提供了更安全、更方便的方式。

一、unique_ptr的特点

(一)独占所有权

unique_ptr拥有它所指向对象的独占所有权。这意味着在同一时间,只有一个unique_ptr可以指向特定的对象。
例如:

#include <memory>
#include <iostream>int main() {std::unique_ptr<int> ptr1 = std::make_unique<int>(10);std::cout << *ptr1 << std::endl;// 以下代码会编译错误,因为不能将一个已经被unique_ptr拥有的对象再交给另一个unique_ptr// std::unique_ptr<int> ptr2 = ptr1;std::unique_ptr<int> ptr2 = std::move(ptr1); // 使用std::move将ptr1的所有权转移给ptr2std::cout << *ptr2 << std::endl;std::cout << *ptr1 << std::endl;//这里在运行时会报错:Segmentation fault (core dumped),因为ptr1已经不再拥有对象了return 0;
}

在这个例子中,ptr1最初拥有一个值为10的int对象。当我们想要将这个对象的所有权转移给ptr2时,不能直接赋值,而是需要使用std::move。这体现了unique_ptr的独占性。
然后注意,在move后,*ptr会报错:Segmentation fault (core dumped),因为ptr1已经不再拥有对象了,debug中也可以看到,move后ptr1就指向地址0了
在这里插入图片描述

(二)对象生命周期管理

当unique_ptr被销毁(例如超出作用域)时,它所指向的对象也会被自动销毁。
例如:

#include <memory>
#include <iostream>struct MyClass {MyClass() { std::cout << "MyClass类对象的构造函数被调用" << std::endl; }~MyClass() { std::cout << "MyClass类对象的析构函数被调用" << std::endl; }
};void function() {std::unique_ptr<MyClass> ptr = std::make_unique<MyClass>();
}int main() {function();return 0;
}

在function函数中,创建了一个MyClass类型的对象,通过unique_ptr来管理。当function函数结束时,ptr超出作用域,MyClass对象的析构函数会被自动调用。

二、shared_ptr的特点

(一)共享所有权

多个shared_ptr可以共享指向同一个对象的所有权。
例如:

#include <memory>
#include <iostream>int main() {std::shared_ptr<int> ptr1 = std::make_shared<int>(20);std::shared_ptr<int> ptr2 = ptr1;std::cout << *ptr1 << " " << *ptr2 << std::endl;return 0;
}

这里ptr1和ptr2都指向同一个int对象,并且可以正常访问该对象的值。

(二)引用计数

shared_ptr内部使用引用计数来管理对象的生命周期。
当一个新的shared_ptr开始共享对象时,引用计数加1;当一个shared_ptr不再指向该对象(例如被重新赋值或者超出作用域)时,引用计数减1。当引用计数为0时,对象才会被销毁。
例如:

#include <memory>
#include <iostream>struct MyClass {MyClass() { std::cout << "MyClass类对象的构造函数被调用" << std::endl; }~MyClass() { std::cout << "MyClass类对象的析构函数被调用" << std::endl; }
};int main() {std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();{std::shared_ptr<MyClass> ptr2 = ptr1;std::cout << "Inside inner block, reference count: " << ptr1.use_count() << std::endl;}std::cout << "Outside inner block, reference count: " << ptr1.use_count() << std::endl;return 0;
}

在这个例子中,在内部代码块中,ptr1和ptr2共享MyClass对象,引用计数为2。当内部代码块结束时,ptr2超出作用域,引用计数减为1。

小测验

下面的代码的打印结果是什么?

shared_ptr<Account> p1 = make_shared<Account>("Alice", 1000.0);
shared_ptr<Account> p2 = p1;
shared_ptr<Account> p3 = p2;cout << p1.use_count() <<endl;
cout << p2.use_count() <<endl;
cout << p3.use_count() <<endl;

答案在最下面

三、unique_ptr和shared_ptr的区别

(一)所有权模式

unique_ptr是独占所有权,而shared_ptr是共享所有权。
如前面的示例所示,unique_ptr不能简单地复制来共享对象,而shared_ptr可以方便地共享。

(二)内存开销

一般情况下,unique_ptr的内存开销比shared_ptr小。
因为shared_ptr需要额外的空间来存储引用计数,而unique_ptr不需要。

(三)使用场景

当对象的所有权明确为独占时,应该使用unique_ptr,例如在函数内部创建一个对象,并且不需要在函数外部共享这个对象时。
当对象需要在多个部分之间共享时,使用shared_ptr比较合适,例如在不同的类或者模块之间共享一个对象。
小测验里,结果都是3,因为是shared_ptr 指向的是一个东西

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

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

相关文章

免费实用的图片加水印工具

高度自定义的图片加水印工具 因工作需要和朋友的需求&#xff0c;我基于canvas开发了这款图片加水印工具。 地址&#xff1a;https://potatotools.top/toolsEntrance/pic/ImageWatermark.vue.html 功能亮点 尺寸定制 &#xff0c;轻松调整水印宽高&#xff0c;精准适配每张图…

数字化工厂 MES 成功之艰:深度剖析与探究

系统集成的复杂性 多源异构系统对接难题 在数字化工厂的建设进程中&#xff0c;MES&#xff08;制造执行系统&#xff09;处于核心枢纽地位&#xff0c;需与众多不同来源、不同架构的系统进行集成。企业内部往往早已部署了诸如企业资源计划&#xff08;ERP&#xff09;系统、…

kimi 大模型 API 接口实现大模型对话 - python 实现

kimi API接口实现大模型对话 - python 实现&#xff0c;具体代码如下&#xff1a; 注意&#xff1a;api_key 需要kimi官网注册后创建。 from openai import OpenAI if __name__ __main__:client OpenAI(api_key "sk-***********", # $MOONSHOT_API_KEY 官网注册…

服务器被隔离导致无法登录

现象描述 云服务器可能会因安全违规&#xff08;内容或行为违规&#xff09;或因 DDoS 攻击被封堵隔离&#xff0c;被隔离的云服务器在控制台显示为 “BANNING” 状态。 云服务器被隔离可能由于该台服务器违反了当前法律法规的要求。您可以通过以下方式查看该台服务器是否处于…

PaddleNLP的环境配置:

PaddleNLP的环境配置&#xff1a; conda create -n paddle—test python3.9conda activate paddle—testpython -m pip install paddlepaddle-gpu2.6.1.post112 -f https://www.paddlepaddle.org.cn/whl/windows/mkl/avx/stable.html(paddle—test) (venv) PS D:\work\论文写…

物联网研究实训室建设方案

一、引言 随着物联网技术的快速发展&#xff0c;其在各个行业的应用越来越广泛&#xff0c;对物联网专业人才的需求也日益增加。为满足这一需求&#xff0c;建设一个符合现代化教学需求的物联网研究实训室&#xff0c;对于提高学生的实践能力和创新能力具有重要意义。本方案旨…

javaweb学习——Day2

JS对象 1、array 定义&#xff1a; var namenew Array(元素列表); var name[元素列表] 访问&#xff1a; name[索引]值 array的属性和方法 length属性&#xff0c;获取数组长度 foreach():遍历数组元素 x.forEach(element > { console.log(element); }); push():…

实战精选|如何使用 OpenVINO™ 在 ElectronJS 中创建桌面应用程序

点击蓝字 关注我们,让开发变得更有趣 作者 | Mikołaj Roszczyk 华沙理工大学物联网工程师 翻译 | 武卓 英特尔 AI 软件布道师 排版 | 吴紫琴 OpenVINO™ 最近&#xff0c;我完成了一个 demo 演示&#xff0c;展示了 OpenVINO™ 在 Node.js 框架中的强大功能。得益于与 Electr…

PyCharm的类型警告: Expected type ‘SupportsWrite[bytes]‘, got ‘BinaryIO‘ instead

记录时使用的PyCharm版本: PyCharm 2024.3 (Professional Edition) Build #PY-243.21565.199, built on November 13, 2024 问题描述 当在PyCharm里使用pickle保存文件, 比如以下代码这样: with open(meta_save_path, wb) as f:pickle.dump(meta, f)会发现PyCharm对此发出类型…

【Docker】快速部署 Pikachu:一个包含常见 Web 安全漏洞的渗透测试练习靶场

系统介绍 Pikachu是一个带有漏洞的Web应用系统&#xff0c;在这里包含了常见的web安全漏洞。 如果你是一个Web渗透测试学习人员且正发愁没有合适的靶场进行练习&#xff0c;那么Pikachu可能正合你意。 Pikachu上的漏洞类型列表如下&#xff1a; Burt Force(暴力破解漏洞) XSS…

vscode 执行 vue 命令无效/禁止运行

在cmd使用命令可以创建vue项目但是在vscode上面使用命令却不行 一、问题描述 在 cmd 中已确认vue、node、npm命令可以识别运行&#xff0c;但是在 vscode 编辑器中 vue 命令被禁止&#xff0c;详细报错为&#xff1a;vue : 无法加载文件 D:\Software\nodejs\node_global\vue.…

【电路笔记 通信】:数字式时分制指令响应型多路传输数据总线 1553协议 289A-97协议

系统及组成 MIL-STD-1553是一种用于航空、航天和军用系统中的多路传输数据总线标准。最初由美国国防部在1973年制定&#xff0c;该标准旨在为军用飞机、导弹和其他嵌入式系统提供可靠的数据通信&#xff0c;现已被广泛应用于航空航天、卫星、舰船、地面车辆以及其他关键任务系统…

npm/cnpm的使用

npm 1、安装npm 前往nodejs官网下载安装node 验证是否安装成功node node -v node安装npm也会安装 npm -v 2、使用npm 1. 初始化项目 在一个项目文件夹中运行&#xff1a; npm init 根据提示输入项目信息&#xff08;如项目名称、版本号等&#xff09;。 如果你希望快速初…

红外相机和RGB相机外参标定 - 无需标定板方案

1. 动机 在之前的文章中红外相机和RGB相机标定&#xff1a;实现两种模态数据融合_红外相机标定-CSDN博客 &#xff0c;介绍了如何利用标定板实现外参标定&#xff1b;但实测下来发现2个问题&#xff1a; &#xff08;1&#xff09;红外标定板尺寸问题&#xff0c;由于标定板小…

web小:在html页面实现多边形按钮

效果如下图所示 主要是使用了clip-path&#xff0c;代码如下 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">&l…

【蓝桥杯C/C++】翻转游戏:多种实现与解法解析

文章目录 &#x1f4af;题目&#x1f4af;问题分析解法一&#xff1a;减法法解法二&#xff1a;位运算解法解法三&#xff1a;逻辑非解法解法四&#xff1a;条件运算符解法解法五&#xff1a;数组映射法不同解法的比较 &#x1f4af;小结 &#x1f4af;题目 在蓝桥镇&#xff0…

V-rep机器人仿真软件学习笔记

常用的机器人仿真软件有哪些&#xff1f;为什么选择V-rep&#xff1f; 目前常用的机器人物理仿真软件有Gazebo、V-rep、Webots等&#xff0c;这三款都是开源软件&#xff0c;自己使用过前两种&#xff0c;Gazebo配合ROS使用功能十分强大&#xff0c;但是要在Linux系统下使用&am…

第7章 硬件测试-7.1 硬件调试

第7章 硬件测试 7.1 硬件调试7.1.1 电路检查7.1.2 电源调试7.1.3 时钟调试7.1.4 主芯片及外围小系统调试7.1.5 存储器件和串口外设调试7.1.6 其他功能模块调试 测试是每项成功产品的必经环节。硬件测试是评估产品质量的重要方法&#xff0c;产品质量是公司的信誉和品牌象征&…

《深入理解 Spring MVC 工作流程》

一、Spring MVC 架构概述 Spring MVC 是一个基于 Java 的轻量级 Web 应用框架&#xff0c;它遵循了经典的 MVC&#xff08;Model-View-Controller&#xff09;设计模式&#xff0c;将请求、响应和业务逻辑分离&#xff0c;从而构建出灵活可维护的 Web 应用程序。 在 Spring MV…

基于Java Springboot宿舍管理系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术&#xff1a;Html、Css、Js、Vue、Element-ui 数据库&#xff1a;MySQL 后端技术&#xff1a;Java、Spring Boot、MyBatis 三、运行环境 开发工具&#xff1a;IDEA/eclipse 数据…