make_shared的使用

目录

1. make_shared 的基本概念

基本用法

2. 引入 make_shared 的主要原因

2.1 解决传统构造方式的问题

2.2 标准委员会的动机

3. make_shared 的核心优势

3.1 性能优势(最重要优点)

内存分配优化:

性能提升表现:

3.2 异常安全(关键优势)

3.3 代码简洁性(显著优势)

配合 auto 使用更清晰:

4. make_shared 的实现原理

4.1 典型实现伪代码


1. make_shared 的基本概念

make_shared 是 C++11 引入的模板函数,用于创建并返回一个指向动态分配对象的 shared_ptr。它是创建共享所有权对象的标准推荐方式。

基本用法
auto ptr = std::make_shared<MyClass>(arg1, arg2...);

2. 引入 make_shared 的主要原因

2.1 解决传统构造方式的问题

传统 shared_ptr 构造方式:

std::shared_ptr<MyClass> ptr(new MyClass(arg1, arg2...));

这种方式存在三个潜在问题:

  • 内存分配分离:需要两次内存分配(对象+控制块)
  • 异常不安全:可能在构造过程中发生内存泄漏
  • 代码冗余:需要重复类型名称

异常导致泄漏的场景

当执行 std::shared_ptr<MyClass> ptr(new MyClass(arg1, arg2...)) 时,实际分为两个关键内存操作:

  • 执行 new MyClass(arg1, arg2...)分配 “对象本身” 的内存,并调用构造函数初始化 MyClass 对象。
  • 构造 shared_ptr分配 “控制块” 的内存(控制块用于记录引用计数、弱引用计数等元信息),然后让 shared_ptr 接管第一步创建的对象。

如果在 ** 步骤 2(分配控制块)** 时发生异常(比如内存不足,抛出 std::bad_alloc),问题就会出现:

  • 步骤 1 已经成功创建了 MyClass 对象(内存已分配,构造函数已执行)。
  • 但步骤 2 失败,shared_ptr 没有被成功构造,也就没有指针能管理第一步创建的对象
  • 最终,这个 new 出来的 MyClass 对象既没有被智能指针接管,也没有被手动 delete,导致内存泄漏(对象的内存永远无法被释放)。
2.2 标准委员会的动机

C++标准委员会引入 make_shared 主要基于:

  • 性能优化:减少内存分配次数
  • 异常安全:保证原子性操作
  • 代码简洁:改善编码体验

3. make_shared 的核心优势

3. make_shared 的核心优势

3.1 性能优势(最重要优点)
内存分配优化:

典型实现的内存布局

make_shared 分配的内存块:
+-------------------+-------------------+
| 控制块 (refcount) | 对象数据          |
+-------------------+-------------------+
性能提升表现:
  • 缓存友好:控制块和对象在同一缓存行
  • 减少碎片:单次分配减少内存碎片
  • 分配更快:内存分配是昂贵操作

基准测试通常显示 make_shared 比传统方式快 10-30%

3.2 异常安全(关键优势)

考虑以下可能抛出异常的代码:

void process(std::shared_ptr<X> x, std::shared_ptr<Y> y);process(std::shared_ptr<X>(new X), std::shared_ptr<Y>(new Y));

问题在于:

  • new X 成功
  • new Y 抛出异常
  • 已分配的 X 内存泄漏

解释

  • 先执行 new X,成功分配了 X 类型的内存,并得到裸指针 X*
  • 接着执行 new Y,但此时内存不足(或其他原因),new Y 抛出异常(比如 std::bad_alloc)。

异常导致 “裸指针未被智能指针接管”

当 new Y 抛出异常时,整个 process 函数的调用会被中断。此时:

  • 第一个参数 std::shared_ptr<X>(new X) 还没完成 “shared_ptr 封装裸指针” 的过程(因为参数计算被异常打断了);
  • 也就是说,new X 分配的内存,只有裸指针,没有被 shared_ptr 接管(智能指针的 “自动释放” 能力没生效)。

使用 make_shared 的解决方案:

process(std::make_shared<X>(), std::make_shared<Y>());

这样要么全部成功,要么全部回滚,不会泄漏资源。

3.3 代码简洁性(显著优势)
// 传统方式(重复类型名)
std::shared_ptr<VeryLongTypeName> p(new VeryLongTypeName(args...));// make_shared 方式(简洁)
auto p = std::make_shared<VeryLongTypeName>(args...);
配合 auto 使用更清晰:
auto widget = std::make_shared<Widget>(color, size);

4. make_shared 的实现原理

4.1 典型实现伪代码
//make_shared的实现
//伪代码
template<typename T, typename... Args>
shared_ptr<T> my_make_shared(Args&& ...args)
{//先开辟控制块和对象大小的空间void* p = ::operator new(sizeof(ContorlBlock) + sizeof(T));//构造控制块ContorlBlock* cb = new(p) ControlBlock();//获取到对象的地址T* obj = reinterpret_cast<T*>(static_cast<char*>(p) + sizeof(ContorlBlock));//给对象进行构造 使用定位new,使用完美转发保持右值属性new(obj) T(std::forward(Args)(args)...);return shared_ptr<T>(cb, obj);
}	

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

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

相关文章

基于 Gemini 的 CI/CD 自动化测评 API 集成实战教程

在现代软件开发中&#xff0c;CI/CD 集成 已经成为必不可少的流程。它不仅能帮助团队快速迭代&#xff0c;还能通过自动化手段提升代码质量。而在编程培训和团队内部学习中&#xff0c;如何引入 自动化测评 API&#xff0c;实现提交即测评、即时反馈呢&#xff1f;本文将以 Gem…

SOME/IP-SD(Service Discovery)协议的核心协议

<摘要> 本解析以AutoSAR AP R22-11版本为基准&#xff0c;全面系统地阐述了SOME/IP-SD&#xff08;Service Discovery&#xff09;协议的核心内容。从车载网络演进背景切入&#xff0c;详细剖析了面向服务架构&#xff08;SOA&#xff09;下服务发现的必要性&#xff0c;…

视频串行解串器(SerDes)介绍

视频串行解串器&#xff08;SerDes&#xff09;是高速数据通信中的核心接口技术&#xff0c;通过串行化与解串行化实现视频信号的高效传输&#xff0c;广泛应用于汽车电子、数据中心、高清视频传输等领域。 一、技术原理串行化&#xff08;Serializer&#xff09; 功能&#xf…

哈士奇vs网易高级数仓:数据仓库的灵魂是模型、数据质量还是计算速度?| 易错题

面试场景 面试官: (微笑,营造轻松但专业的氛围)嗨,哈士奇,欢迎来参加网易的二面。我看你简历上数据仓库的项目经验很丰富,我们今天就深入聊聊。我这里有一个经典的问题想听听你的看法:在你看来,数据仓库的灵魂是模型、数据质量还是计算速度? 哈士奇: (不假思索,…

贪心算法应用:3D打印支撑结构问题详解

Java中的贪心算法应用&#xff1a;3D打印支撑结构问题详解 1. 问题背景与概述 1.1 3D打印中的支撑结构问题 在3D打印过程中&#xff0c;当模型存在悬空部分&#xff08;overhang&#xff09;时&#xff0c;通常需要添加支撑结构&#xff08;support structure&#xff09;来防止…

Python爬虫实战:研究3D plotting模块,构建房地产二手房数据采集和分析系统

1. 引言 1.1 研究背景 在大数据与人工智能技术快速发展的背景下,数据已成为驱动决策的核心要素。互联网作为全球最大的信息载体,蕴含海量结构化与非结构化数据,如何高效提取并分析这些数据成为学术界与产业界的研究热点。 网络爬虫技术通过自动化请求与解析网页,实现数据…

Gradio全解10——Streaming:流式传输的音频应用(7)——ElevenLabs:高级智能语音技术

Gradio全解10——Streaming&#xff1a;流式传输的音频应用&#xff08;7&#xff09;——ElevenLabs&#xff1a;高级智能语音技术10.7 ElevenLabs&#xff1a;高级智能语音技术10.7.1 核心功能与可用模型1. 核心功能与产品2. 三类语音模型10.7.2 文本转语音API1. 完整操作步骤…

【桃子同学笔记4】PCIE训练状态机(LTSSM)基础

首先&#xff0c;所谓LTSSM&#xff0c;即&#xff1a;Link Training and Status State Machine&#xff08;链路训练及状态机&#xff09; 下图为 LTSSM 的状态机及训练过程&#xff1a; LTSSM 包含 11 个顶层状态&#xff1a;Detect、Polling、Configuration、Recovery、L0、…

STM32传感器模块编程实践(十五)DIY语音对话控制+满溢检测智能垃圾桶模型

文章目录 一.概要二.实验模型原理1.硬件连接原理框图2.控制原理 三.实验模型控制流程四.语音控制垃圾桶模型程序五.实验效果视频六.小结 一.概要 以前介绍的智能垃圾桶模型都是通过超声波模块感知控制&#xff0c;这次介绍一款新的智能垃圾桶&#xff0c;直接使用语音交互模块…

[bat-cli] docs | 控制器

链接&#xff1a;https://github.com/sharkdp/bat 前文传送&#xff1a; 【探索Linux命令行】从基础指令到高级管道操作的介绍与实践【Linux命令行】从时间管理-&#xff1e;文件查找压缩的指令详解【Linux】1w详解如何实现一个简单的shell docs&#xff1a;bat bat 是一个*…

无线自动信道调整

通过信道调整功能&#xff0c;可以保证每个AP 能够分配到最优的信道&#xff0c;尽可能地 减少和避免相邻信道干扰&#xff0c;而且通过实时信道检测&#xff0c;使AP 实时避开雷达&#xff0c;微波炉等干扰源。 动态信道调整能够实现通信的持续进行&#xff0c;为网络的可靠传…

ios面试八股文

​​Swift 语言特性​​&#xff1a;请解释一下 struct和 class的主要区别。特性​​​​struct (值类型)​​​​class (引用类型)​​​​类型本质​​值类型 (复制时创建独立副本)引用类型 (复制时共享同一实例)​​内存分配​​通常在栈上 (更快速)在堆上 (需要ARC管理)​​…

IntelliJ IDEA 2023更新git凭据

背景&#xff1a;已知原来从远程仓库获取的项目&#xff0c;需要更新git用户和密码&#xff0c;但是又不想删除本地项目环境&#xff08;不想重新获取新建项目&#xff09;。报错&#xff1a;remote: HTTP Basic: Access denied. The provided password or token is incorrect …

Docker 容器 OOM:从资源监控到JVM调优的实战记录

人们眼中的天才之所以卓越非凡&#xff0c;并非天资超人一等而是付出了持续不断的努力。1万小时的锤炼是任何人从平凡变成超凡的必要条件。———— 马尔科姆格拉德威尔 &#x1f31f; Hello&#xff0c;我是Xxtaoaooo&#xff01; &#x1f308; “代码是逻辑的诗篇&#xff…

【开题答辩全过程】以 基于微信小程序的宠物领养系统为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人&#xff0c;语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

【可信数据空间-连接器状态监控-Java代码集成】

可信数据空间-连接器状态监控-Java代码集成一、 核心概念1. Micrometer2. Micrometer Registry Prometheus3.Prometheus二、 依赖配置 (Maven)三、 集成步骤与代码示例场景一&#xff1a;在 Spring Boot 应用中集成&#xff08;最简单&#xff09;1. 添加依赖&#xff08;如上所…

反编译分析C#闭包

一、问题描述&#xff1a;比如有这样的代码&#xff1a;它的输出结果是 3&#xff0c;3&#xff0c;3。通过搜索得知这一现象是因为C#闭包导致的.我们借助ILSpy看下IL中间代码&#xff0c;首先它生成了一个名叫DisplayClass的类&#xff0c;类中定义了i的字段主代码&#xff1a…

卷积神经网络(CNN):从图像识别原理到实战应用的深度解析

目录一.CNN的技术必要性&#xff1a;破解传统图像处理的两大核心痛点痛点1&#xff1a;特征依赖人工设计&#xff0c;通用性差痛点2&#xff1a;全连接网络参数爆炸&#xff0c;训练难收敛二.CNN的核心原理&#xff1a;两大机制与分层感知逻辑1.核心机制1&#xff1a;局部连接&…

用 SPL 编写阿里云 FC2.0 函数

前言 在数字化转型持续加速的背景下&#xff0c;企业越来越多地将业务逻辑以服务化方式部署至云端。阿里云函数计算&#xff08;Function Compute&#xff0c;简称FC&#xff09;作为一种无服务器计算平台&#xff0c;屏蔽了底层资源运维的复杂性&#xff0c;使开发者能够专注…

AR 巡检与普通巡检有哪些区别,有哪些优势|阿法龙XR云平台

AR 巡检&#xff08;增强现实巡检&#xff09;与普通巡检&#xff08;传统人工巡检&#xff09;在技术应用、效率、准确性等多个维度存在显著差异&#xff0c;具体区别如下&#xff1a; 1. 巡检方式更智能 普通巡检&#xff1a;依赖人工现场观察&#xff0c;主要通过眼看、手…