Make _ only 和 std: : only _ ptr 与 new 之间的差异

std::make_unique有像 std::make_shared一样的效率优势吗?

与手工构建 std::unique_ptr相比:

std::make_unique<int>(1);         // vs
std::unique_ptr<int>(new int(1));
79791 次浏览

std::make_uniquestd::make_shared的存在有两个原因:

  1. 这样就不必显式列出模板类型参数。
  2. 比使用 std::unique_ptrstd::shared_ptr构造函数更安全的异常

这与运行时效率无关。有一点关于控制块和 T被一次性全部分配,但我认为这更多的是一个奖金,而不是这些功能存在的动机。

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*
    
  • The addition of make_unique finally means we can tell people to 'never' use new rather than the previous rule to "'never' use new except when you make a unique_ptr".

There's also a third reason:

  • make_unique does not require redundant type usage. unique_ptr<T>(new T()) -> make_unique<T>()

None of the reasons involve improving runtime efficiency the way using make_shared does (due to avoiding a second allocation, at the cost of potentially higher peak memory usage).

* It is expected that C++17 will include a rule change that means that this is no longer unsafe. See C++ committee papers P0400R0 and P0145R3.

必须直接使用 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并释放它的内存: 内存无声地泄漏,没有办法清理它。通过将 AB包装成 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()来分配对象。