Ete*_*nal 86 c++ unique-ptr c++17
据我所知,引入了C++ 14 std::make_unique,因为由于没有指定参数评估顺序,这是不安全的:
f(std::unique_ptr<MyClass>(new MyClass(param)), g()); // Syntax A
Run Code Online (Sandbox Code Playgroud)
(说明:如果评估首先为原始指针分配内存,则g()在std::unique_ptr构造之前抛出调用和异常,然后内存泄漏.)
呼叫std::make_unique是一种约束呼叫顺序的方法,从而使事情变得安全:
f(std::make_unique<MyClass>(param), g()); // Syntax B
Run Code Online (Sandbox Code Playgroud)
从那以后,C++ 17澄清了评估顺序,使得Syntax A也安全,所以这里是我的问题:在C++ 17中仍然有理由使用std::make_uniqueover std::unique_ptr的构造函数吗?你能举一些例子吗?
截至目前,我能想象的唯一原因是它只允许输入MyClass一次(假设您不需要依赖多态std::unique_ptr<Base>(new Derived(param))).但是,这似乎是一个非常弱的原因,特别是当构造函数std::make_unique不允许指定删除器时std::unique_ptr.
而且为了清楚起见,我并不是主张std::make_unique从标准库中删除(至少为了向后兼容而保持它有意义),而是想知道是否仍然存在强烈倾向于它的情况std::unique_ptr
Nat*_*ica 66
你找对主要原因是对的.仍然没有使用新的指南,并且它的输入原因较少(不必重复类型或使用单词new).不可否认,这些都不是强有力的论据,但我真的不喜欢new在我的代码中看到.
也不要忘记一致性.你绝对应该使用,make_shared所以使用make_unique是自然的,适合模式.然后改变std::make_unique<MyClass>(param)到std::make_shared<MyClass>(param)(或反过来)语法A需要更多重写的地方是微不足道的.
Cal*_*eth 45
make_unique区分T从T[]和T[N],unique_ptr(new ...)没有.
您可以轻松地通过传递这是一个指针得到了一个未定义的行为new[]编的unique_ptr<T>,或传递,这是一个指针new编的unique_ptr<T[]>.
S.M*_*.M. 20
原因是更短的代码没有重复.相比
f(std::unique_ptr<MyClass>(new MyClass(param)), g());
f(std::make_unique<MyClass>(param), g());
Run Code Online (Sandbox Code Playgroud)
你保存MyClass,new并支持.与ptr相比,make中只需要一个字符.
Yak*_*ont 18
每次使用new都必须经过仔细审核才能终身正确; 它会被删除吗?只有一次?
每次使用make_unique都不适合那些额外的特征; 只要拥有对象具有"正确"的生命周期,它就会递归地使唯一指针具有"正确".
现在,确实unique_ptr<Foo>(new Foo())在所有方面都是相同的1到make_unique<Foo>(); 它只需要一个更简单的"grep你的源代码,new用于审计它们的所有用途".
1实际上是一般情况下的谎言.完美转发并不完美,{}默认的init,数组都是例外.