c++ - 带有智能指针的 C++ 工厂模式 - 无法通过“使用已删除函数”错误
问题描述
我正在尝试使用智能指针制作一个小型 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 接受的答案进行更改后,这是一个完整的工作副本/可粘贴示例:
// 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));
然后dog
andcat
将释放它们的指针,并且在调用智能指针的析构函数时不会删除对象。
推荐阅读
- linux - 启动时运行脚本,重启时运行其他脚本
- google-apps-script - 如何在 GoogleSheet 中每 24 小时运行一次函数
- flutter - 在 Flutter 中单击另一个扩展 Tile 后如何折叠已经打开的扩展 Tiles?
- oop - 域对象中的集合属性 - 何时使用?
- reactjs - 反应路由器长嵌套路由
- heroku - 如何使用 big rock 更改我的托管合作伙伴(netlify 到 heroku)?
- apache-spark - 镶木地板内部和火花
- python - 如何在 Django 中同时预测多个 Keras 分类器会话?
- django - 如何在 windows10 中制作 django 站点 https
- c# - 如何将 windows 窗体中多行的动态文本框值插入到数据库中。(使用 C#、Linq-to-SQL 类、SQL Server)