Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::make_unique和std::unique_ptr与new的区别_C++_C++11_C++14_Smart Pointers_Unique Ptr - Fatal编程技术网

C++ std::make_unique和std::unique_ptr与new的区别

C++ std::make_unique和std::unique_ptr与new的区别,c++,c++11,c++14,smart-pointers,unique-ptr,C++,C++11,C++14,Smart Pointers,Unique Ptr,std::make_unique是否有像std::make_shared这样的效率优势 与手动构造std::unique\u ptr相比: std::make_unique<int>(1); // vs std::unique_ptr<int>(new int(1)); std::使_唯一(1);//vs std::unique_ptr(新int(1)); std::make_unique和std::make_shared有两个原因: 这样就不必显式列出

std::make_unique
是否有像
std::make_shared
这样的效率优势

与手动构造
std::unique\u ptr
相比:

std::make_unique<int>(1);         // vs
std::unique_ptr<int>(new int(1));
std::使_唯一(1);//vs
std::unique_ptr(新int(1));

std::make_unique
std::make_shared
有两个原因:

  • 这样就不必显式列出模板类型参数
  • 使用
    std::unique\u ptr
    std::shared\u ptr
    构造函数时的额外异常安全。(请参见注释部分。)

  • 这与运行时效率无关。控制块和
    T
    一次分配有点不对劲,但我认为这更多的是一种奖励,而不是这些功能存在的动机。

    使其独一无二的动机主要有两个方面:

    • make_unique
      对于创建临时表是安全的,而明确使用
      new
      时,您必须记住不使用未命名临时表的规则

      foo(make_unique<T>(), make_unique<U>()); // exception safe
      
      foo(unique_ptr<T>(new T()), unique_ptr<U>(new U())); // unsafe*
      
      foo(make_unique(),make_unique());//例外安全
      foo(unique_ptr(new T()),unique_ptr(new U());//不安全*
      
    • 添加
      make_unique
      最后意味着我们可以告诉人们“永远不要”使用
      new
      ,而不是以前的规则“永远不要”使用
      new
      ,除非你制作了一个
      unique\ptr

    还有第三个原因:

    • make_unique
      不需要重复使用类型
      unique\u ptr(新T())
      ->
      make\u unique()
    没有一个原因涉及到使用
    make_shared
    提高运行时效率的方法(由于避免了第二次分配,以可能更高的峰值内存使用率为代价)


    *预计C++17将包含一个规则更改,这意味着这不再是不安全的。请参阅C++委员会文件和

    < P> >为什么使用<代码> STD::UNQuyjyPTR(new Ar))或<代码> STD::SyrdYpPTR(new A.)(<代码> >直接代替<代码> STD::MaMaj**())/Case>不能访问类< <代码> >当前代码之外的构造函数> < /P> < P>考虑函数调用< /P>
    void function(std::unique_ptr<A>(new A()), std::unique_ptr<B>(new B())) { ... }
    

    这里的要点是:代码> STD::MaMax独占< /COD>和 STD::MaMaIOLION/<代码>现在是临时对象,并且在C++标准中正确地指定临时对象的清理:它们的析构函数将被触发,内存被释放。因此,如果可以,请始终选择使用

    std::make_unique
    std::make_shared

    分配对象
    make_shared
    是否比编写冗长的代码更有效,因为
    make_shared
    可以在单个分配中同时分配对象空间和控制块空间。这样做的代价是,对象不能与控制块分开释放,因此如果您大量使用
    weak_ptr
    ,那么最终可能会使用更多内存。也许这是一个很好的起点,请参阅此链接以获得详细解释:它们也是为了异常安全。@0x499602D2,这是一个很好的补充。对于未来的读者来说,C++17不允许函数参数的交错,因此异常安全的参数不再适用。两个并行
    std::make_-shared
    的内存分配将确保在另一个内存分配发生之前,至少其中一个被包装在智能指针中,因此不会泄漏。更合理的说法是
    std::unique_-ptr
    std::shared_-ptr
    是我们可以告诉人们这样做的原因“切勿使用
    new
    。“@TimothyShields是的,我就是这个意思。只是在C++11中,我们有了
    make_shared
    ,因此
    make_unique
    是以前缺失的最后一个部分。你可以简单地提到,或者链接到,不使用未命名临时变量的原因吗?实际上,从,我得到了它。。。从这个答案中,考虑以下函数调用<代码> f>代码>:<代码> f(UNQuijpPTR(new t),函数,即yAcNeNeWORKE());代码>-引用答案:编译器可以(按顺序)调用:
    newt
    可以抛出的函数()
    唯一的ptr(…)
    。显然,如果你可以抛出的
    函数实际上抛出了,那么你就泄漏了<代码>使_唯一
    防止出现这种情况。我曾经不得不使用std::unique_ptr(new T())的一个原因是T的构造函数是私有的。即使对std::make_unique的调用在类T的公共工厂方法中,它也不会编译,因为std::make_unique的一个底层方法无法访问私有构造函数。我不想成为那个方法的朋友,因为我不想依赖std::make_unique的实现。因此,唯一的解决方案是,在我的工厂中调用T类的new方法,然后将其封装在std::unique_ptr中。
    void function(std::make_unique<A>(), std::make_unique<B>()) { ... }