假设我有一组以下类:
class animal
{
// members, constructors and other methods...
public:
virtual void what_do_you_eat() { cout << "i eat generic food" << endl; }
}
class cat : public animal
{
// members, constructors and other methods...
public:
void what_do_you_eat() { cout << "i eat cat food" << endl; }
}
class dog : public animal
{
// members, constructors and other methods...
public:
void what_do_you_eat() { cout << "i eat dog food" << endl; }
}
我想创建一个列表(任何容器都可以,但我们为这个例子选择 std::list<>
):
std::list<animal> animals
animals.push_back( dog() );
animals.push_back( cat() );
但是当我尝试遍历列表时,我得到了这个输出:
for(auto itr : animals)
{
itr.what_do_you_eat();
}
// output:
// i eat generic food
// i eat generic food
// i eat generic food
// i eat generic food
// ...
然后我尝试制作一个指针列表(std::list<animal *> animals
),输出是正确的,但是这个解决方案有很多问题:
- 因为标准说 STL 容器不能容纳 const 类型,所以我不能使用
std::list<animal * const> animals
的列表。和animals
持有的指针可以在我的程序中的任何地方被覆盖。 - 我需要手动释放它们。
问题:
是否有可能通过对基类的引用将派生类传递到 STL 容器中,并仍然获得正确的输出?
是否有任何解决方法可以在没有指针的情况下正确执行此操作?目前,我正在编写一个严重依赖类继承的项目,我现在被卡住了,因为我需要创建一个不同类型的对象列表(所有这些类型直接或间接继承自一个基类)这似乎是不可能的。
涉及 boost
的解决方案图书馆是可以接受的。
最佳答案
当你处理多态性时,容器必须使用任何类型的指针。
最好使用智能指针,在你的情况下 std::unique_ptr
将完美地完成这项工作。
例如:
std::list<std::unieque_ptr<animal>> animals;
animals.emplace_back(new dog {});
animals.emplace_back(new cat {});
注意基类 animal
必须有一个虚拟析构函数!
最好将其定义为抽象类:
class animal
{
// NO members, NO constructors only pure virtual methods
public:
virtual ~animal() {};
virtual void what_do_you_eat() = 0;
};
关于c++ - 如何从一组派生类创建一个列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45356655/