一、C++ std::make_unique 详解
1、什么是 std::make_unique?
std::make_unique 是 C++14 标准库中引入的一个模板函数,用于创建并返回一个指向动态分配对象的 std::unique_ptr 智能指针。它的主要目的是提供一种更安全、更简洁的方式来创建和管理独占所有权的动态对象。
2、为什么需要 std::make_unique? (与直接 new 对比)
在 std::make_unique 出现之前,创建 std::unique_ptr 通常是这样做的:
std::unique_ptr<MyClass> ptr(new MyClass(arg1, arg2));
这种方式存在一些潜在问题:
- 异常安全风险: 如果在
new操作和unique_ptr构造之间发生了异常(例如在计算构造函数参数时),那么new分配的内存可能无法被unique_ptr接管,从而发生内存泄漏。 - 代码冗余: 需要重复书写类型
MyClass。 - 风格一致性: C++11 提供了
std::make_shared来创建std::shared_ptr,缺少std::make_unique显得不完整。
std::make_unique 解决了这些问题:
auto ptr = std::make_unique<MyClass>(arg1, arg2);
- 异常安全:
std::make_unique在内部一次性完成内存分配和对象构造。如果构造函数参数的计算过程中抛出异常,或者构造函数本身抛出异常,因为此时还没有返回unique_ptr,所以不会有内存泄漏(分配的内存会被自动释放)。 - 简洁性: 使用
auto关键字,避免了类型重复书写,代码更简洁。 - 一致性: 与
std::make_shared的使用方式保持一致。 - 效率: 编译器有机会进行优化。
3、基本语法和用法
std::make_unique 有两种主要形式:
- 数组版本返回的是
std::unique_ptr<T[]>,这与指向单个对象的std::unique_ptr<T>是不同的特化。 - 数组元素会被值初始化(基本类型初始化为 0,类类型调用默认构造函数)。无法在创建数组时指定每个元素的构造参数。
- 访问数组元素使用
operator[]:arr[i] = 42;。
创建动态数组:
template< T> std::unique_ptr<T[]> ;


