【问题标题】:Why initialize unique_ptr with a make_unique call?为什么用 make_unique 调用初始化 unique_ptr?
【发布时间】:2013-05-27 13:47:27
【问题描述】:

取自: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 然后在 = 的右侧输入大量初始化 ..

我错过了什么?

【问题讨论】:

  • 呃,为什么?因为你想要第一件事而不是第二件事?它们不是等价的。 (查看decltype(pb)
  • 这里有一点很清楚,如果你有一个派生的 smart_pointer,你就不能轻易地将它转换为 base。因为不像base *x;并派生出*y;类型层次结构中没有关系。
  • 只是想知道,unique_ptr&lt;base&gt; pb = make_unique&lt;derived&gt;(); 会更简单吗?因为auto的存在并不意味着我们必须使用它。
  • @FredericS:它会稍微短一些,对于不习惯 C++11 的人来说更熟悉,并且因为它涉及隐式转换,所以不太明确。这是否使它“更简单”是一种审美判断。
  • @SanderDeDycker 使用 uniform-init 效果更好:{}

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


【解决方案1】:

嗯,重点是第一个选项使pb 成为unique_ptr&lt;base&gt;,而第二个选项使pb 成为unique_ptr&lt;derived&gt;。在您的情况下两者是否正确取决于您与 pb 的关系 - 但两者绝对不是等价的。

如果您的程序的相关部分需要使用unique_ptr&lt;base&gt;(可能是因为稍后您要让它指向一个不同派生类的实例),那么第二种解决方案根本不可行。

例如:

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"
// ...

【讨论】:

  • @AndyProwl 隐藏证据,是吗?
  • @BartekBanachewicz:我?我永远不会那样做! (...删除您的评论需要多少钱?);)
  • C++ 现在太丑了。我想要我的new/delete 回来!
  • @BoundaryImposition 没有人把它们拿走。你现在只有其他选择了。
【解决方案2】:

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

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

如果是这样,那么对我来说这将是一个值得怀疑的优点..

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

【讨论】:

  • +1 链接到 Herb 的评论(以及你的好答案:)
【解决方案3】:
auto pb = unique_ptr<base>{ make_unique<derived>() };

上面创建了一个unique_ptr&lt;base&gt;,其中包含一个derived

auto pb = make_unique<derived>();

上面创建了一个包含derivedunique_ptr&lt;derived&gt;

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

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

【讨论】:

    猜你喜欢
    • 2014-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    • 2014-12-10
    • 1970-01-01
    相关资源
    最近更新 更多