0

0

c++如何使用std::make_shared_c++智能指针初始化优化【避坑】

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-02-13 14:11:02

|

295人浏览过

|

来源于php中文网

原创

std::make_shared 更优因其一次分配同时构建控制块和对象,避免两次分配的性能损耗、缓存不友好及异常安全问题;要求t有可访问构造函数且非数组,不调用重载operator new。

c++如何使用std::make_shared_c++智能指针初始化优化【避坑】

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

因为 std::make_shared 在一次内存分配中同时构造控制块和对象,而 shared_ptr<t>(new T(args...))</t> 至少需要两次分配(一次给对象,一次给控制块),性能差、缓存不友好,还可能引发异常安全问题——如果控制块分配失败,new T 已执行却无法回滚。

实操建议:

  • 只要能用 std::make_shared,就别手写 shared_ptr 构造函数
  • 它要求类型 T 必须有可访问的构造函数(包括 public 或 friend),且不能是数组类型(make_shared<int></int> 非法)
  • 注意:若类重载了 operator newmake_shared 不会调用它——它使用的是全局或 std::allocator 分配方式

哪些场景下 std::make_shared 会失效或报错

常见编译错误如 error: no matching function for call to 'make_shared',通常源于以下原因:

  • 传入参数无法匹配 T 的任何构造函数(比如私有构造、explicit 构造函数未显式转型)
  • T 是抽象类或含删除/不可访问的拷贝/移动构造函数(但只要能构造实例,一般不影响 make_shared
  • 试图用 make_shared 构造带 private 继承或友元限制的类,而调用点无权访问构造函数
  • 模板推导失败:比如 make_shared<:vector>>(10, 42)</:vector> 没问题,但 make_shared<:vector>>({1,2,3})</:vector> 可能因初始化列表类型推导失败而报错(需加 std::initializer_list 显式标注)

std::make_shared 初始化时的参数转发陷阱

make_shared 内部用完美转发(std::forward)传递参数,这意味着:

简篇AI排版
简篇AI排版

AI排版工具,上传图文素材,秒出专业效果!

下载

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

  • 右值会被移走,原变量后续状态不确定(尤其对 std::move 过来的临时对象要小心)
  • 引用类型参数若绑定到局部变量,而该变量在 make_shared 返回前已析构,会导致悬垂引用(虽然少见,但在 lambda 捕获或自定义分配器中可能出现)
  • 避免把非 const lvalue 引用传给期望右值的构造函数——编译器不会自动转成右值,得手动 std::move

例如:auto p = std::make_shared<:string>(s);</:string> 是拷贝构造;auto p = std::make_shared<:string>(std::move(s));</:string> 才触发移动。

与 std::shared_ptr 构造函数的行为差异细节

两者语义并不完全等价,容易被忽略的点:

  • std::make_shared<t>(args...)</t> 等价于 shared_ptr<t>(new T(std::forward<args>(args)...))</args></t>,不是 shared_ptr<t>(new T{args...})</t> —— 它用的是圆括号构造,不是花括号初始化(即不触发 std::initializer_list 优先匹配)
  • Texplicit 构造函数,make_shared 仍可调用;但若误写成 make_shared<t>({a,b})</t>,可能意外匹配到 initializer_list 版本,而你本意是普通构造
  • 自定义删除器无法通过 make_shared 设置(它只支持默认删除器),必须用 shared_ptr 构造函数

真正需要自定义删除器、或必须复用已有裸指针时,才放弃 make_shared。其余情况,它就是更安全、更快、更简洁的选择。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
scripterror怎么解决
scripterror怎么解决

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

351

2023.10.18

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

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

326

2023.10.25

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

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

543

2023.09.20

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

211

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

191

2025.11.08

Python lambda详解
Python lambda详解

本专题整合了Python lambda函数相关教程,阅读下面的文章了解更多详细内容。

58

2026.01.05

function是什么
function是什么

function是函数的意思,是一段具有特定功能的可重复使用的代码块,是程序的基本组成单元之一,可以接受输入参数,执行特定的操作,并返回结果。本专题为大家提供function是什么的相关的文章、下载、课程内容,供大家免费下载体验。

491

2023.08.04

js函数function用法
js函数function用法

js函数function用法有:1、声明函数;2、调用函数;3、函数参数;4、函数返回值;5、匿名函数;6、函数作为参数;7、函数作用域;8、递归函数。本专题提供js函数function用法的相关文章内容,大家可以免费阅读。

166

2023.10.07

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

8

2026.02.13

热门下载

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

精品课程

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

共94课时 | 9.3万人学习

C 教程
C 教程

共75课时 | 4.7万人学习

C++教程
C++教程

共115课时 | 17.5万人学习

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

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