在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;
};
具有具体的子类
Cat
和Dog
: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