0

0

c++怎么使用std-make-shared_c++智能指针推荐写法【规范】

尼克

尼克

发布时间:2026-03-14 08:22:31

|

342人浏览过

|

来源于php中文网

原创

std::make_shared 更安全因一次分配控制块与对象,避免异常时资源泄漏;但不可用于私有构造、需自定义删除器或特殊内存布局场景,且参数转发易致悬空引用。

c++怎么使用std-make-shared_c++智能指针推荐写法【规范】

std::make_shared 为什么比 new + shared_ptr 构造更安全

因为 std::make_shared 在一次内存分配中同时构造控制块和对象,避免了两次分配(new 对象 + new 控制块)可能引发的异常安全问题。如果 new 对象成功但控制块分配失败,手动构造的 shared_ptr 会导致资源泄漏。

  • 常见错误现象:shared_ptr<t>(new T(args...))</t> 在构造参数里抛异常时,T 已分配但无法被管理,泄漏
  • 使用场景:只要不需要自定义删除器、不需要从裸指针转换、不涉及继承关系中的多态删除,就该优先用 std::make_shared
  • 性能影响:减少一次内存分配+释放,尤其在高频创建时可观;某些实现还会做小对象优化(把控制块和对象紧邻布局)

哪些情况不能用 std::make_shared

std::make_shared 要求类型必须可公开访问构造函数,且不能绕过构造逻辑——它本质上是调用 T(args...)。一旦你依赖私有构造、委托构造、或需要延迟初始化,它就失效。

  • 常见错误现象:编译报错 error: 'T::T(...)' is privateno matching function for call to 'make_shared'
  • 典型场景:
    • 类只有私有/受保护构造函数(如单例、工厂封装)
    • 需要传入自定义删除器(比如用 fclose 管理 FILE*
    • 对象需先分配内存再 placement-new(如对齐要求特殊、或与内存池集成)
  • 替代写法:老老实实用 shared_ptr<t>(new T(...), [](T* p){ /* custom cleanup */ })</t>,但务必确保异常安全

std::make_shared 的参数转发陷阱

它完美转发参数给 T 的构造函数,但容易忽略引用折叠和临时对象生命周期——尤其是传入非 const lvalue 引用参数时。

  • 常见错误现象:传入局部变量引用,对象构造后引用悬空,但 make_shared 内部已将该引用绑定到即将被移动/销毁的临时对象
  • 关键差异:make_shared 的参数在函数体内被转发,不是在调用者作用域延长生命周期;而直接 new T(x) 中的 x 是调用者负责生命周期
  • 安全做法:
    • 只传值或 const lvalue 引用(const std::string& 安全)
    • 避免传非常量左值引用(std::string& 危险)
    • 不确定时,显式拷贝:用 make_shared<t>(s.c_str(), s.size())</t> 而非 make_shared<t>(s)</t>(若 T 构造函数接受 std::string&& 可能窃取)

和 std::shared_ptr 构造函数的兼容性细节

std::make_shared 返回的是 shared_ptr<t></t>,类型完全一致,但内部布局不同——控制块和对象共分配,导致 shared_ptr 的别名构造(aliasing constructor)行为不变,但地址比较需注意。

AIBox 一站式AI创作平台
AIBox 一站式AI创作平台

AIBox365一站式AI创作平台,支持ChatGPT、GPT4、Claue3、Gemini、Midjourney等国内外大模型

下载

立即学习C++免费学习笔记(深入)”;

  • 常见错误现象:误以为 make_shared<t>()->get() == ptr.get()</t> 在所有情况下都成立(其实仅当没用别名构造时才成立)
  • 兼容性影响:所有标准操作(resetswapuse_count)完全一致;唯一区别是内存布局,不影响 ABI 或接口
  • 特别提醒:不要对 make_shared 创建的对象取地址再转成其他智能指针(如 unique_ptr),控制块不会被识别,析构会崩溃

事情说清了就结束。最常被忽略的是参数转发时的临时对象生命周期,以及误以为 make_shared 能绕过访问控制——它不能。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1051

2023.08.02

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1569

2023.10.24

java多态详细介绍
java多态详细介绍

本专题整合了java多态相关内容,阅读专题下面的文章了解更多详细内容。

27

2025.11.27

fclose函数的用法
fclose函数的用法

fclose是一个C语言和C++中的标准库函数,用于关闭一个已经打开的文件,是文件操作中非常重要的一个函数,用于将文件流与底层文件系统分离,释放相关的资源。更多关于fclose函数的相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

344

2023.11.30

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

492

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

382

2023.10.25

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

564

2023.09.20

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1958

2023.10.19

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 11.3万人学习

C 教程
C 教程

共75课时 | 5.4万人学习

C++教程
C++教程

共115课时 | 21.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号