带有智能指针的 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));
然后dog
和cat
会在调用智能指针的析构函数时释放它们的指针,不会删除对象。
我正在尝试制作一个带有智能指针的小型 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));
然后dog
和cat
会在调用智能指针的析构函数时释放它们的指针,不会删除对象。