如何使用unique_ptr作为需要基类作为参数的函数的参数

时间:2017-02-26 02:00:21

标签: c++ polymorphism unique-ptr

我正在学习使用托管指针,特别是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
}

2 个答案:

答案 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));