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

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

在将所有权转移到另一个unique_ptr时,这在什么情况下有用?

最佳答案

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

假设您有一些多态类型Animal:

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

具有具体的子类CatDog:
struct Cat : Animal {
  void speak() override { std::cout << "Meow!\n"; }
};

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

并且您想要一个简单的工厂,可以根据所需的服从值来创建宠物。然后工厂必须返回一个指针。我们希望宠物工厂将创建的宠物的所有权转让给 call 者,因此合理的返回类型为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>();
}

现在,假设我们要创建一个拥有宠物的House,然后我们可能要将宠物传递到House的构造函数中。关于如何最好地将unique_ptr传递给构造函数,存在一些争论(see comments on this blog post),但是看起来像这样:
class House {
 private:
  std::unique_ptr<Animal> pet_;
 public:
  House(std::unique_ptr<Animal> pet) : pet_(std::move(pet)) {}
};

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

调用代码可能类似于:
  auto pet = createPet(6.0);
  House house(std::move(pet));

构造了House之后,pet变量将为nullptr,因为我们已将宠物的所有权转让给House

Live demo

10-08 08:20