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

c++14之std::make_unique

基础介绍

虽然在c++11版本std::unique_ptr<T>已经引入,但是在c++14版本引入之前,std::unique_ptr<T>的创建还是通过new操作符来完成的。在c++14版本已经引入了类似make_shared的std::make_unique,目的是提供更加安全的方法创建std::unique_ptr<T>,防止产生资源泄露等问题。

为什么要引入std::make_unique<T>?

首先请看下面这句话:

std::make_unique is the recommended way to create instances of std::unique_ptrs due to the following reasons:

  • Avoid having to use the new operator.

       避免使用new操作符

  • Prevents code repetition when specifying the underlying type the pointer shall hold.

        避免类型重复,结合auto关键字可以使用类型推导

  • Most importantly, it provides exception-safety. 

        最重要的是,它提供了异常安全

 下面我们着重分析一下第2点和第3点,先说第二点,避免代码重复(code repetition),应该按下面的方式理解:

//不使用std::make_unique
// 需要重复写类型名
std::unique_ptr<std::vector<std::string>> ptr(new std::vector<std::string>());// 模板类中更麻烦
template<typename T>
class Container {std::unique_ptr<std::vector<T>> data(new std::vector<T>());
};//使用std::make_unique
// 类型推导,无需重复
auto ptr = std::make_unique<std::vector<std::string>>();// 模板类中更简洁
template<typename T>
class Container {auto data = std::make_unique<std::vector<T>>();
};

现在分析最重要的第3点,即为什么std::make_unique可以提供异常安全。看下面的例子:

foo(std::unique_ptr<T>{new T{}}, function_that_throws(), std::unique_ptr<T>{new T{}});

上例中foo函数为什么不安全呢?原因是编译器并不会规定参数求值的执行顺序,那么可能是顺序是:

  1. 执行new T(参数一)
  2. 执行new T (参数二)
  3. 执行function_that_throws() --抛出异常
  4. 构造std::unique_ptr<T> 参数一
  5. 构造std::unique_ptr<T> 参数二

我们知道std::unique_ptr<T>自身可以管理资源,当std::unique_ptr<T>对象出了其作用后会自动释放资源,但是如果在第3步的时候,抛出了异常,导致后面的std::unique_ptr<T>对象未创建成功,则会导致内存泄露。

而使用std::make_unique<T>方式创建对象,如下所示:

foo(std::make_unique<T>(), function_that_throws(), std::make_unique<T>());

std::make_unique可以保证参数一创建完成,即生成std::unique_ptr<T>后再执行后面的操作,此时由于std::unique_str<T>对象已经生成,即使后续抛出异常,那么这块内存也会得到释放。

http://www.lryc.cn/news/536747.html

相关文章:

  • 服务器linux操作系统安全加固
  • 原生Three.js 和 Cesium.js 案例 。 智慧城市 数字孪生常用功能列表
  • Node.js中Express框架使用指南:从入门到企业级实践
  • spring 学习 (注解)
  • 计算机等级考试——计算机三级——网络技术部分
  • 新版电脑通过wepe安装系统
  • oracle中decode怎么转换成pg
  • 【NLP】循环神经网络RNN
  • Linux嵌入式完整镜像烧写到SD卡中的方法(包括对SD卡的介绍)
  • vscode怎么更新github代码
  • 回顾Golang的Channel与Select第二篇
  • 基于mediapipe深度学习的手势数字识别系统python源码
  • JS实现大文件切片上传以及断点续传
  • AI编程01-生成前/后端接口对表-豆包(或Deepseek+WPS的AI
  • 小众宝藏分子生物学实验中常用的软件:InSequence
  • 【自学笔记】机器学习基础知识点总览-持续更新
  • HCIA综合项目之多技术的综合应用实验
  • [免费]Springboot+Vue医疗(医院)挂号管理系统【论文+源码+SQL脚本】
  • 网络基础 【UDP、TCP】
  • Linux centos8部署maven3.9.9
  • 谈谈云计算、DeepSeek和哪吒
  • 链表(典型算法思想)—— OJ例题算法解析思路
  • 【C++指南】解锁C++ STL:从入门到进阶的技术之旅
  • LeetCode刷题---字符串---859
  • 数据处理中多线程功能的设计逻辑,及python的多线程实现
  • DeepSeek-R1技术革命:用强化学习重塑大语言模型的推理能力
  • python中的深度学习框架TensorFlow 和 PyTorch 有什么区别?
  • 用 Python 实现 DeepSeek R1 本地化部署
  • Spreadjs与GcExcel
  • vue中使用lodash的debounce(防抖函数)