1

私は C++ と OOP を独学しようとしている新しいプログラマーです。現在、私は複数の状態を持つプロジェクトに取り組んでおり、より大きなプログラミング タスク/チャレンジへの最初の試みです。現在、単純なメニュー状態クラスに取り組もうとしていますが、やりたいことを実行するためにどのように設計すればよいかわかりません。具体的には、私は初心者のプログラマーであり、どのデータ型またはテンプレートを使用すればよいかわかりません。

作成したいメニュー画面のタイプの簡単な説明は次のとおりです。

複数の「メニュー要素」がリストされた単純なメニュー画面を作成しようとしています。各「メニュー要素」には、文字列 (要素または項目の名前を表示するために使用される) と機能 (状態、画面の変更、タスクの実行など) が含まれます。- 私が持ちたいメニューシステムのもう一つの「機能」は、選択をラップアラウンドする機能です。たとえば、メニューに 3 つの項目がある場合、ユーザーが上下に押して現在選択されている要素を切り替えられるようにしたいのですが、ユーザーが最後の要素 (#3) にいてもう一度押すと、元に戻ります。要素 #1 の周り。(およびその逆..)

さて、これには「MenuElement」と呼ばれる新しいクラスと、ユーザーが特定の要素を切り替えて選択できるようにする「MenuState」と呼ばれるクラスを作成する必要があると思います。

独学の新しい C++ プログラマーとして、私はいくつかのより高度なコンテナーの経験が限られており、単純な C スタイルの配列に精通しています。ベクトルの経験が少しあり、リンクされたリスト、マップ、およびツリーについて少し知っていますが、この状況でどのコンテナー タイプを使用すればよいかわかりません。以前、ポインターを使用して循環リンク リストを作成する例を見たことがありますが、その例は C で書かれており、少しぎこちないように思えました。私の問題に最適な特定の種類のコンテンツはありますか? それとも、考えすぎて、1 つを選択して実行する必要がありますか?

最終的には、一連の条件付きステートメントを含む MenuElements の配列を使用して、このシステムを稼働させることができると思います。ただし、プログラミングと設計を改善する方法を実際に学ぶことに非常に興味があります。これにより、コードがより高速に実行されるようになるだけでなく、コードがクリーンで論理的に構築されるようになります。

4

1 に答える 1

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()現在のメニューのサイズです。

一般的な設計上の質問については、クラス階層のスケッチでComposite Design Pattern ( 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()sinceは subMenus の動的更新を可能にするメンバー関数であることに注意してください(つまり、メニュー項目のドラッグ アンド ドロップを可能にします)。

于 2012-09-11T06:10:34.503 に答える