为什么要使用make_unique调用初始化unique_ptr?

时间:2013-05-27 13:47:28

标签: c++ c++11 c++14 gotw

取自:http://herbsutter.com/2013/05/22/gotw-5-solution-overriding-virtual-functions/

我们为什么要写:

auto pb = unique_ptr<base>{ make_unique<derived>() };

而不仅仅是:

auto pb = make_unique<derived>();

我唯一的猜测是,如果我们想要auto,我们需要帮助它推断出正确的类型(base此处)。

如果是这样,那么对我而言,这将是真正值得怀疑的......输入auto然后在=的右侧输入大量初始化..

我错过了什么?

3 个答案:

答案 0 :(得分:10)

嗯,重点是第一个选项使pb成为unique_ptr<base>,而第二个选项使pb成为unique_ptr<derived>。在你的情况下两者是否正确取决于你与pb的关系 - 但绝对两者并不相同。

如果程序的相关部分需要使用unique_ptr<base>(可能因为稍后您将指向不同的派生类的实例),那么第二种解决方案根本不可行。

例如:

auto pb = unique_ptr<base>{ make_unique<derived>() };
// ...
pb = make_unique<derived2>(); // This is OK
// ...

鉴于:

auto pb = make_unique<derived>();
// ...
pb = make_unique<derived2>(); // ERROR! "derived2" does not derive from "derived"
// ...

答案 1 :(得分:6)

  

我唯一的猜测是,如果我们想要自动,我们需要帮助它推断出正确的类型(基于此处)。

这是完全正确的。如果没有转换,pb将是derived的指针,可能不是您想要的。例如,您无法将其重新分配给拥有base或其他派生类对象。

  

如果是这样,那么对我来说这将是非常值得怀疑的。

我倾向于同意。作者在comment中注意到他这样做是因为他喜欢尽可能多地使用类型推导,并在必要时进行明确的转换。时间将证明这种风格是否会变得司空见惯。

答案 2 :(得分:4)

auto pb = unique_ptr<base>{ make_unique<derived>() };

以上内容会创建一个unique_ptr<base>,其中包含derived

auto pb = make_unique<derived>();

以上内容会创建一个unique_ptr<derived>,其中包含derived

虽然用第一个替换第二个是可以接受的,但它们实际上做了不同的事情。

顺便说一句,在链接文章中搜索make_unique会导致有人在那里回答这个问题。