如何将唯一_PTR参数传递给构造函数或函数?

如何将唯一_PTR参数传递给构造函数或函数?

我刚开始在C+11中移动语义,我不太清楚如何处理unique_ptr构造函数或函数中的参数。考虑这个类引用自身:

#include <memory>class Base{
  public:

    typedef unique_ptr<Base> UPtr;

    Base(){}
    Base(Base::UPtr n):next(std::move(n)){}

    virtual ~Base(){}

    void setNext(Base::UPtr n)
    {
      next = std::move(n);
    }

  protected :

    Base::UPtr next;};

我应该这样写函数吗unique_ptr争吵?

我需要用std::move在电话密码里?

Base::UPtr b1;Base::UPtr b2(new Base());b1->setNext(b2); //should I write b1->setNext(std::move(b2)); instead?


慕无忌1623718
浏览 377回答 3
3回答

杨__羊羊

以下是将唯一指针作为参数的可能方法,以及它们的相关含义。(A)按价值计算Base(std::unique_ptr<Base>&nbsp;n) &nbsp;&nbsp;:&nbsp;next(std::move(n))&nbsp;{}为了让用户调用它,他们必须执行以下操作之一:Base&nbsp;newBase(std::move(nextBase));Base&nbsp;fromTemp(std::unique_ptr<Base>(new&nbsp;Base(...));通过值获取唯一指针意味着转移指向有关函数/对象/etc的指针的所有权。后newBase被建造,nextBase保证空空..你不拥有这个对象,你甚至没有指向它的指针。它不见了。这是确保的,因为我们采用了参数的值。std::move实际上移动什么都行,只是个花哨的演员而已。std::move(nextBase)返回Base&&的r值引用。nextBase..这就是它所能做的。因为Base::Base(std::unique_ptr<Base> n)根据值而不是r值引用它的论点,C+将自动为我们构造一个临时的。它创建一个std::unique_ptr<Base>从Base&&我们通过std::move(nextBase)..实际上,这个临时的建筑移动从nextBase函数参数n.(B)非Const l值参考Base(std::unique_ptr<Base>&nbsp;&n) &nbsp;&nbsp;:&nbsp;next(std::move(n))&nbsp;{}这必须在实际的l-值(一个命名变量)上调用。不能用这样的临时方式调用它:Base&nbsp;newBase(std::unique_ptr<Base>(new&nbsp;Base));&nbsp;//Illegal&nbsp;in&nbsp;this&nbsp;case.它的含义与任何其他非const引用的含义相同:函数可以也可能不会声明指针的所有权。鉴于此代码:Base&nbsp;newBase(nextBase);不能保证nextBase是空的。它可以,可能是空的;它可能不是。这真的取决于什么Base::Base(std::unique_ptr<Base> &n)想做什么。因此,仅仅从函数签名中可以看出将要发生的事情并不是很明显;您必须阅读实现(或相关的文档)。因此,我不建议把它作为一个接口。(C)由Const l-Base(std::unique_ptr<Base>&nbsp;const&nbsp;&n);我没有显示一个实现,因为你不可能从一个const&..通过一个const&,您是说函数可以访问Base通过指针,但它不能商店任何地方。它不能声称拥有它的所有权。这可能很有用。不一定适合你的具体情况,但总能给某人一个指针,并且知道他们不可能(不违反C+的规则,就像没有抛弃const)声称拥有它的所有权。他们不能储存。他们可以把它传给别人,但其他人必须遵守同样的规则。(D)按r-Base(std::unique_ptr<Base>&nbsp;&&n) &nbsp;&nbsp;:&nbsp;next(std::move(n))&nbsp;{}这与“非Const l-value Reference”的情况大致相同。区别是两件事。你,你们能,会,可以临时通过:Base&nbsp;newBase(std::unique_ptr<Base>(new&nbsp;Base));&nbsp;//legal&nbsp;now..你,你们必使用std::move在传递非临时参数时。后者才是真正的问题。如果你看到这一行:Base&nbsp;newBase(std::move(nextBase));你有一个合理的期望,在这一行完成之后,nextBase应该是空的。它应该被移开的。毕竟,你有std::move坐在那里告诉你运动已经发生了。问题是它没有。它不是保被移出。它可以,可能已被移除,但您只能通过查看源代码才能知道。您不能只从函数签名中分辨出来。建议(A)按价值计算:如果你想让一个函数声称所有权一种unique_ptr用价值来衡量。(C)Const l-参考价值:如果您的意思是让一个函数简单地使用unique_ptr在该函数执行期间,请按const&..或者,传递一个&或const&指向的实际类型,而不是使用unique_ptr.(D)按r值计算:如果一个函数可以或不声明所有权(取决于内部代码路径),那么请通过&&..但我强烈建议不要在可能的情况下这样做。如何操作UNIQUE_PTR您不能复制unique_ptr..你只能移动它。正确的方法是使用std::move标准图书馆功能。如果你unique_ptr从价值上说,你可以自由地离开它。但实际上并不是因为std::move..采取以下声明:std::unique_ptr<Base>&nbsp;newPtr(std::move(oldPtr));这实际上是两种说法:std::unique_ptr<Base>&nbsp;&&temporary&nbsp;=&nbsp;std::move(oldPtr);std::unique_ptr<Base>&nbsp;newPtr(temporary);(注意:上面的代码没有技术上的编译,因为非临时的r值引用实际上不是r值.)它在这里只是为了演示的目的)。这个temporary的r值引用。oldPtr..它在构造器的newPtr运动发生的地方。unique_ptr的移动构造函数(接受&&对自己来说)是什么实际的运动。如果你有unique_ptr如果你想把它藏在某个地方,你必使用std::move去做储藏室。

ITMISS

是的,如果你拿了unique_ptr构造函数中的值。解释是件好事。自unique_ptr不可复制(私有副本ctor),您所写的应该会给您一个编译器错误。
打开App,查看更多内容
随时随地看视频慕课网APP