0

我正在尝试为我要编写的一个小程序实现一个菜单结构。

MenuItem 包含一个标签、一个关联函数、一个到其父级的链接和一个包含对其子级的引用的向量。然后是Menu,主要负责选择一个新的MenuItem,并跟踪当前哪个Item处于活动状态。不幸的是,当我在 Menu 中使用 MenuItem 并将当前的 MenuItem 更改为它的一个子项时,我无法再进一步,因为以下子项列表为空。似乎向量没有被正确复制。我试图实现一个复制构造函数,但这没有帮助。这是我的来源如下。

#include <iostream>
#include <sstream>
#include <string>
#include <vector>

typedef void (*fptr)(int);

using namespace std;

void test(int i)
{
    cout << "test function called with argument: " << i << endl;
}

class MenuItem
{
private:
    vector<MenuItem*> children;
    string label;
    fptr f;
    MenuItem* parent;
public:
    MenuItem(string newLabel, fptr newFunction = NULL):label(newLabel),f(newFunction)
    {
    }

    void addChild(MenuItem& mi)
    {
        mi.parent = this;
        children.push_back(&mi);
    }

    MenuItem* getChild(int i)
    {
        return children[i];
    }

    MenuItem* getParent()
    {
        return parent;
    }

    string getLabel()
    {
        return label;
    }

    int countChildren()
    {
        return children.size();
    }

    void list()
    {
        vector<MenuItem*>::iterator i;
        for(i = children.begin(); i < children.end(); ++i)
        {
            MenuItem* m = *i;
            label = m->label;
            stringstream s;
            s << (i - children.begin());
            cout << s.str() << ": " << label << endl;
        }
    }

    void invoke(int i)
    {
        f(i);
    }
};

class Menu
{
private:
    MenuItem* current;
public:
    Menu(MenuItem* m)
    {
        current = m;
        open(0);
    }

    void open(int i)
    {
        current = current->getChild(i);
        if(current->countChildren() > 0)
        {
            cout << "[" << current->getLabel() << "]" << endl;
            current->list();
        }
        else
            current->invoke(i);
    }

    void back(int i)
    {
        current = current->getParent();
    }
};

int main() {
    MenuItem m1("Root");
        MenuItem m2("List Media");
            MenuItem m6("List Movies",&test);
            MenuItem m7("List Music",&test);
            MenuItem m8("List Games",&test);
            MenuItem m9("List Books",&test);
        MenuItem m3("Find Media");
            MenuItem m10("Find Movies",&test);
                MenuItem m14("Find by title",&test);
                MenuItem m15("Find by genre",&test);
            MenuItem m11("Find Music",&test);
                MenuItem m16("Find by title",&test);
                MenuItem m17("Find by genre",&test);
            MenuItem m12("Find Games",&test);
                MenuItem m18("Find by title",&test);
                MenuItem m19("Find by genre",&test);
            MenuItem m13("Find Books",&test);
                MenuItem m20("Find by title",&test);
                MenuItem m21("Find by genre",&test);
        MenuItem m4("Add Media");
            MenuItem m22("Add Movie",&test);
            MenuItem m23("Add Music",&test);
            MenuItem m24("Add Game",&test);
            MenuItem m25("Add Book",&test);
        MenuItem m5("Delete Media");
            MenuItem m26("Add Movie",&test);
            MenuItem m27("Add Music",&test);
            MenuItem m28("Add Game",&test);
            MenuItem m29("Add Book",&test);

    m1.addChild(m2);
        m2.addChild(m6);
        m2.addChild(m7);
        m2.addChild(m8);
        m2.addChild(m9);
    m1.addChild(m3);
        m3.addChild(m10);
            m10.addChild(m14);
            m10.addChild(m15);
        m3.addChild(m11);
            m11.addChild(m16);
            m11.addChild(m17);
        m3.addChild(m12);
            m12.addChild(m18);
            m12.addChild(m19);
        m3.addChild(m13);
            m13.addChild(m20);
            m13.addChild(m21);
    m1.addChild(m4);
        m4.addChild(m22);
        m4.addChild(m23);
        m4.addChild(m24);
        m4.addChild(m25);
    m1.addChild(m5);
        m5.addChild(m26);
        m5.addChild(m27);
        m5.addChild(m28);
        m5.addChild(m29);

    Menu m(&m1);

    int option;
    while(1){
        cout << "Media Library> ";
        cin >> option;
        m.open(option);
    }
}
4

1 回答 1

0

这个问题似乎open(0);在 Menu 的构造函数中。这当然会导致您自动进入“列表媒体”部分,该部分没有进一步的子部分。

这可能应该替换为current->list();

于 2012-05-02T02:17:49.157 回答