具有unique_ptr-s的向量

Vector with unique_ptr-s

本文关键字:向量 ptr-s unique 具有      更新时间:2023-10-16

我有这样的代码:

#include <memory>
#include <vector>
namespace daq
{
class Animal
{
public:
    Animal(){};
};
class Pig : public Animal
{
public:
    Pig() : Animal () {};
};
class Farm
{
public:
    void addAnimal(Animal& animal)
    {
        mAnimals.push_back(std::unique_ptr<Animal>(animal)); // error
    }
private:
    std::vector<std::unique_ptr<Animal>> mAnimals;
};
} /* namespace daq */

但我得到错误的方法农场::addAnimal:

没有匹配的函数调用' std::unique_ptr::unique_ptr(daq::Animal&) '

我应该传递什么给push_back方法?

unique_ptr接受指针作为构造函数参数,但是您传递的是引用。这基本上就是编译器告诉你的:你不能从一个daq::Animal&构造一个std::unique_ptr

您可以传递一个原始指针到new分配的Animal类型的对象,或者(最好)您应该传递一个以这种方式构造的unique_ptr,并在作为push_back()的参数提供时从它移动:

void addAnimal(std::unique_ptr<Animal>&& animal)
//                                    ^^
//                                    This is to make it absolutely clear that
//                                    your intention is to bind to an object
//                                    the client wants to move from. It is not
//                                    especially needed here (unique_ptr is not
//                                    copyable), but it makes your interface
//                                    more explicit about it. [Credits to sehe]
{
    mAnimals.push_back(std::move(animal)); // OK
}
int main()
{
    daq::Farm farm;
    std::unique_ptr<daq::Animal> pig(new daq::Pig());
    farm.addAnimal(std::move(pig)); // OK
}

你必须在这里使用std::move(),因为unique_ptr s是不可复制的,所以你有效地将pig的所有权从调用它的例程转移到包含它的向量(addAnimal()是这个转移的中间)。