设计一个环绕的菜单? C ++ / OOP

时间:2012-09-11 05:45:24

标签: c++ oop class menu containers

我是一名新的程序员,试图自学C ++和OOP。现在我正在开展一个有多个州的项目,这是我第一次尝试更大的编程任务/挑战。现在我正在尝试一个简单的菜单状态类,但我不知道如何设计它来做我想要的。具体来说,我是初学程序员,我不确定要使用哪些数据类型或模板。

以下是我想要制作的菜单屏幕类型的简要说明:

我正在尝试制作一个简单的菜单屏幕,其中列出了多个'菜单元素'每个'menu element'包含一个字符串(用于显示元素或项目的名称)和一个函数(用于更改状态,屏幕,执行任务等)。 - 我想要的菜单系统的其他“功能”是选择环绕的能力。例如,如果菜单有3个项目,我希望用户能够向上和向下按下以切换当前选定的元素,如果用户在最后一个元素(#3)上并再次按下,则它们会回退元素#1。 (反之亦然......)

现在,我想〜这需要我创建一个名为'MenuElement'的新类,以及一个名为'MenuState'的类,它包含并允许用户在特定元素之间切换和选择。

作为一名新的,自学成才的C ++程序员,我对一些更高级的容器的经验有限,而且我对简单的c风格数组更熟悉。我对矢量有一点经验,我对链表,地图和树有一点了解,但我不确定在这种情况下使用哪种容器类型。我以前见过使用指针创建循环链表的例子,但是例子是在C中,它看起来有点笨拙。 是否有特定类型的包含符合我的问题?或者我是否过度思考,我应该选择一个并运行它?

我想我最终可以使用带有一系列条件语句的MenuElements数组来启动和运行这个系统。但是,我真的很想学习如何改进我的编程和设计,不仅让我的代码运行得更快,而且我的代码也是干净的逻辑构造。

1 个答案:

答案 0 :(得分:2)

可以使用模运算完成环绕,即将活动光标的名为idx_的私有成员索引变量赋予菜单元素数组,您可以拥有成员函数page_down()page_up()喜欢这个

void CompositeMenu::page_down()
{
    // idx_ will always remain in the interval [0, num_elements() )
    // when idx_ equals num_elements() - 1, page_down() will yield 0 (i.e. wrap-around)
    idx_ = (idx_ + 1) % num_elements(); 
}

void CompositeMenu::page_up()
{
    // idx_ will always remain in the interval [0, num_elements() )
    // when idx_ equals 0, page_up() will yield num_elements() - 1 (i.e. wrap-around) 
    idx_ = (idx_ - 1 + num_elements() ) % num_elements() ;
}

其中num_elements()是当前菜单的大小。

对于一般设计问题,类层次结构的草图将使用复合设计模式Wikipedia)。这定义了一个名为IMenu的抽象菜单界面,并将CompositeMenuLeafMenu作为具体类派生。这允许嵌套子菜单的任意级别

class IMenu
{
public:
    virtual void SomeOperation() = 0;
};

class CompositeMenu
:
    public IMenu
{
public:
    virtual void SomeOperation() 
    { 
        // your implementation 
    }

    void page_down();  // use implementation above      
    void page_up();    // use implementation above
    int num_elements { return subMenus_.size(); }

private:
    std::vector<IMenu*> subMenus_; // list of subMenus, which can also have nested menus themselves
    int idx_; // active menu element
};

class LeafMenu
:
    public IMenu
{
public:
    virtual void SomeOperation()
    {
        // your implementation
    }
};

请注意,因为num_elements()是一个成员函数,允许在子菜单上进行动态更新(即允许拖放菜单项)。