抽象和派生结合std :: list

时间:2018-07-21 14:07:39

标签: c++ c++11

我正在努力解决以下问题:

我有一个名为Parent的父类和许多不同的名为Child1, Child2, etc的子类。 现在,我最终想要做的是拥有一个std::list或某种容器来保存和访问一堆不同的子对象及其派生函数

例如:

Parent.h

class Parent
{
public:
    Parent();

    virtual void logic() = 0;

    //strings and other members of every Child
}

Child1.h

class Child1 : public Gate
{
public:
    Child1 ();
    ~Child1 ();
    void logic();
};

Child1.cpp

void Child1::logic()
{ //Do Stuff }

现在让我们说我想拥有一个std::list或最适合我的Abstract类Parents的任何容器

main.cpp

std::list <Parent> foo;

我将如何用不同类型的子代填充列表,以及如何遍历此列表并调用每个子代的logic()函数?

我读了很多关于使用unique_ptr,使用dynamic cast或使用vector而不是列表的帖子,但在这一点上,我比以前更加困惑。

1 个答案:

答案 0 :(得分:2)

首先使用std::unique_ptr<Parent>而不是Parent,否则您将遭受object slicing的困扰。

接下来,只需要用对象填充容器并调用其logic(),例如:

std::vector<std::unique_ptr<Parent>> objects;
objects.push_back(std::make_unique<Child1>());
objects.push_back(std::make_unique<Child2>());
objects.push_back(std::make_unique<Child3>());

for(const auto& child : objects)
  child->logic();

当然可以对std::list进行相同的操作,但是在这里更喜欢std::vector


#include <iostream>
#include <memory>
#include <vector>
class Parent
{
public:
    Parent() {}

    virtual void logic() = 0;

    //strings and other members of every Child
};

class Child1 : public Parent
{
public:
    void logic() override { std::cout << "Hi from Child1." << std::endl; }
};

class Child2 : public Parent
{
public:
    void logic() override { std::cout << "Hi from Child2." << std::endl; }
};

class Child3 : public Parent
{
public:
    void logic() override { std::cout << "Hi from Child3." << std::endl; }
};

int main() {
    std::vector<std::unique_ptr<Parent>> objects;
    objects.push_back(std::make_unique<Child1>());
    objects.push_back(std::make_unique<Child2>());
    objects.push_back(std::make_unique<Child3>());

    for(const auto& child : objects)
      child->logic();
    return 0;
}

Working example