C++ 具有唯一_ptr-s的向量
我有这样的代码:C++ 具有唯一_ptr-s的向量,c++,c++11,move-semantics,C++,C++11,Move Semantics,我有这样的代码: #include <memory> #include <vector> namespace daq { class Animal { public: Animal(){}; }; class Pig : public Animal { public: Pig() : Animal () {}; }; class Farm { public: void addAnimal(Animal& animal) {
#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 */
#包括
#包括
名称空间数据采集
{
类动物
{
公众:
动物{};
};
猪类:公共动物
{
公众:
猪():动物(){};
};
阶级农场
{
公众:
动物(动物和动物)
{
mAnimals.push_back(std::unique_ptr(动物));//错误
}
私人:
std::矢量模型;
};
}/*名称空间daq*/
但是我在方法Farm::addAnimal中得到错误:
调用“std::unique\u ptr::unique\u ptr(daq::Animal&)”时没有匹配的函数
我应该向push_-back方法传递什么?A
unique\u ptr
接受指针作为构造函数参数,但您正在传递引用。这基本上就是编译器告诉您的:您不能从daq::Animal&
构造std::unique\u ptr
您可以传递一个原始指针,指向分配了new
的Animal
类型的对象,或者(最好)传递一个以这种方式构造的unique\u ptr
,并在将其作为push\u back()的参数提供时从中移出:
void addAnimal(std::unique_ptr&&animal)
// ^^
//这是为了清楚地表明
//您的意图是绑定到一个对象
//客户想要离开。事实并非如此
//这里特别需要(不需要唯一的ptr
//可复制),但它使您的界面
//更明确地说。[贷记sehe]
{
推回(标准::移动(动物));//好
}
int main()
{
daq:农场;
std::unique_ptr pig(新的daq::pig());
farm.addAnimal(std::move(pig));//好的
}
您必须在此处使用std::move()
,因为unique\u ptr
s是不可复制的,所以您实际上是在将pig
的所有权从调用它的例程转移到包含它的向量(addAnimal()
是此转移的中间层).您应该传递一个指针。如果您希望存储通过引用接收的项的动态副本(std::unique_ptr),则必须使元素类型(Animal)可克隆。但是出于样式的原因,将参数作为右值引用“接收”(记录移动语义)不是更好吗<代码>无效添加动物(标准::唯一动物)
@sehe:你的意思是,接收一个动物&&
并执行farm.addAnimal(std::move(Animal))
?我的意思是更改现有的addAnimal(而不是添加另一个重载)@sehe:这就是我的意思:更改现有的addAnimal()
以接收一个动物&
,并通过执行farm.addAnimal(std::move>来调用它(动物)
。这就是你的建议吗?@sehe:我想说的是,这会破坏引用语义(尽管不清楚这里是否需要它)。客户端可能希望保留一个指向它添加到农场的动物的观察指针。另一方面,如果不需要引用语义,则mAnimals
可以是vector
,并且addAnimal()
的参数可以完美地转发到mAnimals
。
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
}