std::make_unique和std::unique_ptr与new之间的差异
Differences between std::make_unique and std::unique_ptr with new
std::make_unique
与std::make_shared
一样具有效率优势吗?
与手动构建std::unique_ptr
:相比
std::make_unique<int>(1); // vs
std::unique_ptr<int>(new int(1));
make_unique
背后的动机主要有两方面:
-
make_unique
对于创建临时库是安全的,而显式使用new
时,您必须记住不使用未命名临时库的规则。foo(make_unique<T>(), make_unique<U>()); // exception safe foo(unique_ptr<T>(new T()), unique_ptr<U>(new U())); // unsafe*
-
make_unique
的添加最终意味着我们可以告诉人们"永远不要"使用new
,而不是之前的规则"除非你制作unique_ptr
,否则永远不要使用new
"。
还有第三个原因:
make_unique
不需要使用冗余类型。unique_ptr<T>(new T())
->make_unique<T>()
这些原因都不涉及像使用make_shared
那样提高运行时效率(因为避免了第二次分配,代价是潜在的更高峰值内存使用率(。
*预计C++17将包含一个规则更改,这意味着它不再是不安全的。参见C++委员会文件P0400R0和P0145R3。
std::make_unique
和std::make_shared
的存在有两个原因:
- 这样就不必显式地列出模板类型的参数
- 使用
std::unique_ptr
或std::shared_ptr
构造函数的额外异常安全性。(请参阅此处的"注释"部分。(
这实际上与运行时效率无关。有一点是关于控制块和T
同时被分配的,但我认为这更多是一种奖励,而不是这些功能存在的动机。
必须直接使用std::unique_ptr(new A())
或std::shared_ptr(new A())
而不是std::make_*()
的一个原因是无法在当前作用域之外访问类A
的构造函数。
考虑函数调用
void function(std::unique_ptr<A>(new A()), std::unique_ptr<B>(new B())) { ... }
假设new A()
成功,但new B()
抛出一个异常:您捕获它以恢复程序的正常执行。不幸的是,C++标准并不要求对象A
被销毁并释放其内存:内存悄悄地泄漏,而且没有办法清理它。通过将A
和B
封装到std::make_unique()
调用中,可以确保不会发生泄漏:
void function(std::make_unique<A>(), std::make_unique<B>()) { ... }
这里的要点是std::make_unique<A>()
和std::make_unique<B>()
返回临时对象,并且在C++标准中正确地指定了临时对象的清理:它们的析构函数将被触发,内存将被释放。因此,如果可以的话,总是倾向于使用std::make_unique()
和std::make_shared()
来分配对象。
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 为什么 std::unique 不调用 std::sort?
- 我对 std::unique(算法)C++有问题
- std::shared_ptr::unique(),复制和线程安全
- 如何在C++03中用自定义谓词调用std::unique
- C++ std::unique并没有显示我对它的期望
- C++14 unique_ptr并使用已删除的函数'std::unique-ptr' unique_ptr错误
- 为什么 [std::unique] 不能应用于 [std::multiset]?
- 使用 std::unique 和 vector.erase 删除除最后一次出现的重复元素之外的所有元素
- 是否可以在 std::unique<T[ ]> 上应用 std::sort?
- std::unique 是否有大小限制
- 从 std::unique 返回的迭代器的用法
- 使 std::unique<T> 与 std::unique<const T, CustomDeleterType 兼容>
- Std::list.unique()应该使迭代器无效
- 无法使用初始化器列表构造 vector<std::unique<...>>
- 从自定义对象- std:unique的向量中消除重复项会导致崩溃
- 我能保证std::unique将保留第一个元素吗?
- 在 std::vector<std::unordered_set上使用 std::unique(<T>>