在 C++11 中将对象的所有权从一个 unique_ptr 转移到另一个 unique_ptr?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26318506/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 11:34:41  来源:igfitidea点击:

Transferring the ownership of object from one unique_ptr to another unique_ptr in C++11?

c++c++11stdmove-semantics

提问by Roy

In C++11we can transfer the ownership of an object to another unique_ptrusing std::move(). After the ownership transfer, the smart pointer that ceded the ownership becomes nulland get()returns nullptr.

C++11我们可以将对象的所有权转移到另一个unique_ptr使用std::move()。所有权转移后,转让所有权的智能指针变为nullget()返回nullptr.

std::unique_ptr<int> p1(new int(42));
std::unique_ptr<int> p2 = std::move(p1); // Transfer ownership

What are the situations where this will be useful as it is transferring the ownership to another unique_ptr?

在什么情况下这会在将所有权转让给另一个人时有用unique_ptr

回答by Chris Drew

The following situations involve transferring ownership from one unique_ptrto another: returning from a function, and passing as a parameter to a function like a constructor.

以下情况涉及将所有权从一个转移unique_ptr到另一个:从函数返回,并作为参数传递给像构造函数这样的函数。

Say you have some polymorphic type Animal:

假设你有一些多态类型Animal

struct Animal {
  virtual ~Animal() {}
  virtual void speak() = 0;
};

with concrete subclasses Catand Dog:

具有具体的子类CatDog

struct Cat : Animal {
  void speak() override { std::cout << "Meow!\n"; }
};

struct Dog : Animal {
  void speak() override { std::cout << "Woof!\n"; }
};

And you want a simple factory that creates a pet based on a required value of obedience. Then the factory must return a pointer. We want the pet factory to transfer ownership of the created pet to the caller so a reasonable return type is std::unique_ptr<Animal>:

并且您想要一个简单的工厂,根据所需的服从值来创建宠物。然后工厂必须返回一个指针。我们希望宠物工厂将创建的宠物的所有权转移给调用者,因此合理的返回类型是std::unique_ptr<Animal>

std::unique_ptr<Animal> createPet(double obedience) {
  if (obedience > 5.0)
    return std::make_unique<Dog>();
  return std::make_unique<Cat>();
} 

Now, say we want to create a Housethat will own the pet then we might want to pass the pet into the constructor of the House. There is some debate (see comments on this blog post) about how best to pass a unique_ptrto a constructor but it would look something like this:

现在,假设我们要创建一个House将拥有宠物的对象,然后我们可能希望将宠物传递给House. 关于如何最好地将 a 传递给构造函数存在一些争论(请参阅此博客文章的评论),unique_ptr但它看起来像这样:

class House {
 private:
  std::unique_ptr<Animal> pet_;
 public:
  House(std::unique_ptr<Animal> pet) : pet_(std::move(pet)) {}
};

We have passed the unique_ptrinto the constructor and have then "moved" it to the member variable.

我们已将 传递给unique_ptr构造函数,然后将其“移动”到成员变量中。

The calling code could look something like:

调用代码可能类似于:

  auto pet = createPet(6.0);
  House house(std::move(pet));

After constructing the House, the petvariable will be nullptrbecause we have transferred ownership of the pet to the House.

构造 后Housepet变量将是nullptr因为我们已将宠物的所有权转移到House

Live demo

Live demo

回答by user2485710

for example if you call a function you can moveyour unique_ptrin the parameter list so it can be a part of your function signature

例如,如果你调用一个函数,你可以moveunique_ptr在参数列表中,因此它可以是你的函数签名的一部分

foo ( std::unique_ptr<T>&& ptr )

you can call foo with

你可以打电话给 foo

foo( std::move(myPtr) );

Note that std::moveis an unconditional cast and unique_ptris an object with a state, and a part of that state is the pointer that that unique_ptris managing, with std::moveyou are casting the entire object, you are not really changing anything about ownership, there is nothing peculiar about std::unique_ptrwhile using std::movebecause std::movedoesn't really care about anything specific, as I said it is an unconditional cast and unique_ptrsimply gets casted, the entire object that is an instance of type unique_ptr<T>is casted .

请注意,这std::move是一个无条件转换并且unique_ptr是一个具有状态的对象,该状态的一部分是unique_ptr正在管理的指针,当std::move您正在转换整个对象时,您并没有真正改变所有权,没有什么特别之处std::unique_ptr在使用时,std::move因为std::move并不真正关心任何特定的东西,正如我所说,它是一个无条件强制转换并且unique_ptr只是被强制转换,作为类型实例的整个对象unique_ptr<T>被强制转换。

If you want to talk about a transfer of ownership of the object pointed by your unique_ptr, you should consider the swapprovided by std::unique_ptr<T>itself .

如果你想谈论你所指向的对象的所有权转让unique_ptr,你应该考虑swapstd::unique_ptr<T>它自己提供。