我正在学习使用托管指针,特别是unique_ptr。
我已经实现了这些简单的类,但函数makeAnimalNoise()不起作用,即使我认为我传递了正确的参数。
makeAnimalNoise()函数有什么问题?这个函数的正确参数应该是什么?或者定义本身是错误的?
class Animal{
public:
Animal(){
cout<<"An animal is born"<<endl;
}
virtual ~Animal(){
cout<<"An animal dies"<<endl;
}
virtual void doAnimalStuff()=0;
};
class Dog: public Animal{
public:
Dog(){
cout<<"A dog is born"<<endl;
}
~Dog() {
cout<<"A dog dies"<<endl;
}
void doAnimalStuff() override {
cout<<"I'm a dog"<<endl;
}
};
class Cat: public Animal{
public:
Cat(){
cout<<"A cat is born"<<endl;
}
~Cat() {
cout<<"A cat dies"<<endl;
}
void doAnimalStuff() override {
cout<<"I'm a cat"<<endl;
}
};
void makeAnimalNoise(unique_ptr<Animal>an){
an->doAnimalStuff();
}
int main(){
unique_ptr<Animal>Dog=unique_ptr<Dog>(new Dog());
unique_ptr<Animal>Cat=unique_ptr<Cat>(new Cat());
makeAnimalNoise(Dog); //doesn't work here
makeAnimalNoise(Cat); //doesn't work here
}
答案 0 :(得分:7)
您不希望将所有权转移到makeAnimalNoise
功能中。智能指针只应由责任人的所有者使用;你绝对应该不用智能指针替换所有你的代码。
您的功能应该只是参考:
void makeAnimalNoise(Animal& an) {
an.doAnimalStuff();
}
在通话现场:
makeAnimalNoise(*Dog);
makeAnimalNoise(*Cat);
重复一遍:当指针对象的所有权是API的主题时,智能指针应该只出现在API中。如果只关注指针对象的值,请使用引用或普通指针参数。
以另一种方式说:智能指针是管理责任的工具,而不是传递值或实现引用语义。
答案 1 :(得分:2)
makeAnimalNoise
的参数被声明为按值传递;但std::unique_ptr
无法复制;你可以像
unique_ptr<Animal> dog(new Dog);
unique_ptr<Animal> cat(new Cat);
makeAnimalNoise(std::move(dog));
makeAnimalNoise(std::move(cat));