在列表中调用子对象方法的最佳方法是?

时间:2017-11-15 01:08:11

标签: c++

我正在尝试创建一个所有继承基类的GUI元素系统。我希望能够通过在父类中调用Draw方法来调用所有子元素。这基本上是我到目前为止所拥有的:

基本元素:

interface GuiElementBase
{
protected:
    std::vector<GuiElementBase> children;
public: 
    void Draw()
    {
        for (int i = 0; i < children.size(); i++)
            children[i].Draw();
    }
    void AddChild(GuiElementBase child)
    {
        children.push_back(child);
    }
};

文字元素:

class GuiElementText : public GuiElementBase
{
public:
    void Draw()
    {
        GuiElementBase::Draw();
        // + some text-specific drawing code
    }
};

实现:

GuiElementText* TextTest;

void GUI::Init()
{
    TextTest = new GuiElementText();
    TextTest->AddChild(GuiElementText());
}

void GUI::Draw()
{
    TextTest->Draw();
}

为简单起见,遗漏了构造函数,绘图代码和其他方法。

当它尝试更新TextTest子项时,它显然只是调用GuiElementBase :: Draw(),因为&#34; children&#34; vector是GuiElementBase。我一直在找不到让它调用子对象而不是基类的方法。非常感谢所有帮助!

1 个答案:

答案 0 :(得分:0)

在下面的示例中,首先执行基础Draw(),然后为vector中的每个子项执行Draw()。这就是你要追求的吗?

#include <iostream>

class GuiElementBase
{
private:
    std::vector<GuiElementBase *> children;
public:
    virtual void Draw()
    {
        std::cout << "GuiElementBase draw" << std::endl;

        for (int i = 0; i < children.size(); i++)
            children[i]->Draw();
    }
    void AddChild(GuiElementBase *child)
    {
        children.push_back(child);
    }
};

class GuiElementText : public GuiElementBase
{
public:
    void Draw() override
    {
        std::cout << "GuiElementText draw" << std::endl;
    }
};


int main()
{
    GuiElementBase base;
    GuiElementText* child = new GuiElementText();

    base.AddChild(child);
    base.AddChild(child);

    base.Draw();

    return 0;
}

打印:

GuiElementBase draw
GuiElementText draw
GuiElementText draw