我是一名新的程序员,试图自学C ++和OOP。现在我正在开展一个有多个州的项目,这是我第一次尝试更大的编程任务/挑战。现在我正在尝试一个简单的菜单状态类,但我不知道如何设计它来做我想要的。具体来说,我是初学程序员,我不确定要使用哪些数据类型或模板。
以下是我想要制作的菜单屏幕类型的简要说明:
我正在尝试制作一个简单的菜单屏幕,其中列出了多个'菜单元素'。 每个'menu element'包含一个字符串(用于显示元素或项目的名称)和一个函数(用于更改状态,屏幕,执行任务等)。 - 我想要的菜单系统的其他“功能”是选择环绕的能力。例如,如果菜单有3个项目,我希望用户能够向上和向下按下以切换当前选定的元素,如果用户在最后一个元素(#3)上并再次按下,则它们会回退元素#1。 (反之亦然......)
现在,我想〜这需要我创建一个名为'MenuElement'的新类,以及一个名为'MenuState'的类,它包含并允许用户在特定元素之间切换和选择。
作为一名新的,自学成才的C ++程序员,我对一些更高级的容器的经验有限,而且我对简单的c风格数组更熟悉。我对矢量有一点经验,我对链表,地图和树有一点了解,但我不确定在这种情况下使用哪种容器类型。我以前见过使用指针创建循环链表的例子,但是例子是在C中,它看起来有点笨拙。 是否有特定类型的包含符合我的问题?或者我是否过度思考,我应该选择一个并运行它?
我想我最终可以使用带有一系列条件语句的MenuElements数组来启动和运行这个系统。但是,我真的很想学习如何改进我的编程和设计,不仅让我的代码运行得更快,而且我的代码也是干净的逻辑构造。
答案 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
的抽象菜单界面,并将CompositeMenu
和LeafMenu
作为具体类派生。这允许嵌套子菜单的任意级别。
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()
是一个成员函数,允许在子菜单上进行动态更新(即允许拖放菜单项)。