Ответ 1
Следующие ситуации включают перенос права собственности с одного 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"; }
};
И вам нужен простой factory, который создает домашнее животное на основе требуемого значения послушания. Затем factory должен вернуть указатель. Мы хотим, чтобы домашнее животное factory передало право собственности на созданное домашнее животное вызывающему, поэтому разумный тип возврата 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
, но он будет выглядеть примерно так
class House {
private:
std::unique_ptr<Animal> pet_;
public:
House(std::unique_ptr<Animal> pet) : pet_(std::move(pet)) {}
};
Мы передали unique_ptr
в конструктор и затем "переместили" его в переменную-член.
Код вызова может выглядеть примерно так:
auto pet = createPet(6.0);
House house(std::move(pet));
После построения House
переменная pet
будет nullptr
, потому что мы передали права собственности на домашнее животное на House
.