带有智能指针的 C++ 工厂模式 - 无法通过 "use of deleted function" 错误

C++ Factory Pattern with Smart Pointers - can't get past "use of deleted function" error

我正在尝试制作一个带有智能指针的小型 C++ 工厂模式示例。这是我目前所拥有的:

// FactorySmart.cpp

#include <iostream>
#include <vector>
#include <memory>

enum AnimalSpecies { dog, cat };

class Animal
{
public:
  virtual void makeSound() = 0;
};

class Dog : public Animal
{
public:
  void makeSound() { std::cout << "woof" << "\n\n"; }
};

class Cat : public Animal
{
public:
  void makeSound() { std::cout << "meow" << "\n\n"; }
};

class AnimalFactory
{
public:
  static std::unique_ptr<Animal> makeAnimal(AnimalSpecies animalSpecies);
};

std::unique_ptr<Animal> AnimalFactory::makeAnimal(AnimalSpecies animalSpecies)
{
  if (animalSpecies == AnimalSpecies::dog)
  {    
    return(std::make_unique<Dog>());   
  }
  else if (animalSpecies == AnimalSpecies::cat)
  {    
    return(std::make_unique<Cat>());    
  }
  else
  {
    std::cout << "error in AnimalFactory::makeAnimal(), animalSpecies = " << animalSpecies << " does not seem to be valid" << "\n\n";
    return(nullptr);
  }
}

int main(void)
{  
  std::vector<std::unique_ptr<Animal>> animals;

  std::unique_ptr<Animal> dog = AnimalFactory::makeAnimal(AnimalSpecies::dog);
  animals.push_back(dog);

  std::unique_ptr<Animal> cat = AnimalFactory::makeAnimal(AnimalSpecies::cat);
  animals.push_back(cat);

  for (auto &animal : animals)
  {
    animal->makeSound();
  }

  return(0);
}

使用 GCC 7.3 我得到:

error: use of deleted function

使用 Visual Studio 2019 附带的 Microsoft 编译器,我得到:

attempting to reference a deleted function

如果我注释掉这些行,错误就会消失,所以这似乎是我出错的地方:

std::unique_ptr<Animal> dog = AnimalFactory::makeAnimal(AnimalSpecies::dog);
animals.push_back(dog);

std::unique_ptr<Animal> cat = AnimalFactory::makeAnimal(AnimalSpecies::cat);
animals.push_back(cat);

我在 Stack Overflow 和其他地方看过非常相似的例子,但我似乎无法弄清楚我哪里出错了。有什么建议吗?

--- 编辑 ---

根据以下 Kit 接受的答案进行更改后,这是一个完整的工作 copy/pastable 示例:

// FactorySmart.cpp

#include <iostream>
#include <vector>
#include <memory>

enum AnimalSpecies { dog, cat };

class Animal
{
public:
  virtual void makeSound() = 0;
};

class Dog : public Animal
{
public:
  void makeSound() { std::cout << "woof" << "\n\n"; }
};

class Cat : public Animal
{
public:
  void makeSound() { std::cout << "meow" << "\n\n"; }
};

class AnimalFactory
{
public:
  static std::unique_ptr<Animal> makeAnimal(AnimalSpecies animalSpecies);
};

std::unique_ptr<Animal> AnimalFactory::makeAnimal(AnimalSpecies animalSpecies)
{
  if (animalSpecies == AnimalSpecies::dog)
  {
    std::unique_ptr<Animal> dog = std::make_unique<Dog>();
    return(dog);
  }
  else if (animalSpecies == AnimalSpecies::cat)
  {
    std::unique_ptr<Animal> cat = std::make_unique<Cat>();
    return(cat);
  }
  else
  {
    std::cout << "error in AnimalFactory::makeAnimal(), animalSpecies = " << animalSpecies << " does not seem to be valid" << "\n\n";
    return(nullptr);
  }  
}

int main(void)
{
  std::vector<std::unique_ptr<Animal>> animals;

  std::unique_ptr<Animal> dog = AnimalFactory::makeAnimal(AnimalSpecies::dog);
  animals.push_back(std::move(dog));

  std::unique_ptr<Animal> cat = AnimalFactory::makeAnimal(AnimalSpecies::cat);
  animals.push_back(std::move(cat));

  for (auto &animal : animals)
  {
    animal->makeSound();
  }  

  return(0);
}

在您的 animals.push_back() 中,您正试图复制 unique_ptr<>,这是不允许的。

改为使用:

std::unique_ptr<Animal> dog = AnimalFactory::makeAnimal(AnimalSpecies::dog);
animals.push_back(std::move(dog));

std::unique_ptr<Animal> cat = AnimalFactory::makeAnimal(AnimalSpecies::cat);
animals.push_back(std::move(cat));

然后dogcat会在调用智能指针的析构函数时释放它们的指针,不会删除对象。