What happens to unique_ptr after std::move()?

心已入冬 提交于 2020-05-22 19:20:06

问题


This code is what I want to do:

Tony& Movie::addTony()
{
    Tony *newTony = new Tony;
    std::unique_ptr<Tony> tony(newTony);
    attachActor(std::move(tony));
    return *newTony;
}

I am wondering if I could do this instead:

Tony& Movie::addTony()
{
    std::unique_ptr<Tony> tony(new Tony);
    attachActor(std::move(tony));
    return *tony.get();
}

But will *tony.get() be the same pointer or null? I know I could verify, but what is the standard thing for it to do?


回答1:


No, you cannot do that instead. Moving the unique_ptr nulls it. If it didn't, then it would not be unique. I am of course assuming that attachActor doesn't do something silly like this:

attachActor(std::unique_ptr<Tony>&&) {
    // take the unique_ptr by r-value reference,
    // and then don't move from it, leaving the
    // original intact
}

Section 20.8.1 paragraph 4.

Additionally, u (the unique_ptr object) can, upon request, transfer ownership to another unique pointer u2. Upon completion of such a transfer, the following postconditions hold:
   -- u2.p is equal to the pre-transfer u.p,
   -- u.p is equal to nullptr, and
   -- if the pre-transfer u.d maintained state, such state has been transferred to u2.d.




回答2:


The standard says (§ 20.8.1.2.1 ¶ 16, emphasis added) that the move constructor of std::unique_ptr

unique_ptr(unique_ptr&& u) noexcept;

Constructs a unique_ptr by transferring ownership from u to *this.

Therefore, after you move-construct the temporary object that gets passed as argument to attachActor form your tony, tony no longer owns the object and hence tony.get() == nullptr. (This is one of the few cases where the standard library actually makes assertions about the state of a moved-away-from object.)

However, the desire to return the reference can be fulfilled without resorting to naked new and raw pointers.

Tony&
Movie::addTony()
{
  auto tony = std::make_unique<Tony>();
  auto p = tony.get();
  attachActor(std::move(tony));
  return *p;
}

This code assumes that attachActor will not drop its argument on the floor. Otherwise, the pointer p would dangle after attachActor has returned. If this cannot be relied upon, you'll have to re-design your interface and use shared pointers instead.

std::shared_ptr<Tony>
Movie::addTony()
{
  auto tony = std::make_shared<Tony>();
  attachActor(tony);
  return tony;
}


来源:https://stackoverflow.com/questions/36071220/what-happens-to-unique-ptr-after-stdmove

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!