c++ - 如何从一组派生类创建一个列表?

标签 c++ inheritance std

假设我有一组以下类:

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/

相关文章:

c# - 继承 C# Tuple<T, T>,同时向构造函数添加值检查。

c++ - 无法设置 std::map 元素?

c++ - 调用 CMD.exe 后立即返回的 VC++ std::system() API

c++ - 使用指向对象的指针初始化不可复制的第三方基类

c++ - 有可能有一个动画 QSystemTrayIcon 吗?

c++ - 如何在 C++ 中使用共享/弱指针干净地实现两个引用彼此的对象?

c++ - 请让我理解将派生类对象分配给基类指针- C++

java - 如何使用泛型在 Java 中创建通用方法?

c++ - 优化 std::deque 中的搜索

c++ - 使用 cin 检查用户整数输入会产生无限循环