私はC++とPythonの両方でコンソールメニューを作成しましたが、クラスの構造について質問しているので、ここでは言語はそれほど大きな役割を果たしていないと思います。
つまり、私が達成しようとしているのは、MS-DOSに似たメニューであり、親メニュー(フォルダー)とアクションメニュー(ファイル)を使用できます。印刷すると、コンソールでどのように表示されるかを次に示します。
[-] Root directory
Open snakegame
[-] First sub directory
Print out stupid messages
[+] Closed directory in open directory
Shutdown computer
[+] These directories are closed
[+] You can't see the content inside them
Quit menu
ご覧のとおり、ここには2種類のメニューがあります。
- ディレクトリ(MS-DOSフォルダ)メニュー。他のメニューをその中に保持します。起動すると、開閉します。例:
Root directory
が開いており、その中のすべてのメニューを見ることができます。閉じられるとに[-]
変わり[+]
、他のメニューは表示されなくなります。 - 関数にリンクされているアクション(MS-DOSファイル)メニュー。有効にすると、リンク先の関数を呼び出します。例:メニューを閉じてヘビゲームを開始する
Open snakegame
関数にリンクすることができます。startSnakeGame()
必要な結果を得るために、すでに2つの実用的な実装をコーディングしましたが、どちらを使用すればよいのでしょうか。最初の方法は、と呼ばれるクラスが1つだけで、Menu
すべてのメンバー変数とメソッドが1つのクラスにコード化されている場合です。もう1つの方法は、これら2つの異なるタイプのメニューを2つのクラスに分け、共通の基本クラスを使用することです。
ここにいくつかのメンバー変数があります。ここではそれらを3つのセクション(基本クラス、ディレクトリクラス、アクションクラス)に分割しますが、1つのクラスに組み合わせることができます。
基本メニュー:
parent
=子としてリスト/ベクトル内に保持されるメニュー(ディレクトリ1)this/self
(以下を参照)。label
=明らかに、メニューの印刷時に表示されるラベル。selected
=メニューが現在選択されているかどうかを示すブール値(マウスでポイントされている場合など)。
ディレクトリメニュー:
subMenus
=リストまたはその中に他のメニューを保持するベクトル(C ++の場合)。open
=メニューが開いているか閉じているかを示すブール値。
アクションメニュー:
action
=このメニューがアクティブになったときに呼び出される関数へのポインタ。
ご覧のとおり、他のクラスと異なる変数はごくわずかであり、action == 0
(アクションなしで)メニューが現在の値open
に応じて自動的に変わるように設定できます。false/true
このようにして、アクションメニューは終了しますが、唯一の欠点は、アクションメニューが保持されて使用subMenus
されclosed
ないことです。
これはすべて自分の意見かもしれませんが、私はこれについてしばらく考えていましたが、他の方法よりも優れた方法を見つけることができませんでした。どちらにも長所と短所があり、どちらもうまく機能します。だから私はあなたの意見について尋ねています、そして誰かが彼らがどちらかを選ぶ理由があるかどうか聞いてみたいです。基本的に私は理由を尋ねています、私はあなたの意見を気にしません。
フォルダとファイル以外のメニュータイプはないため、基本クラスを他の目的に使用することはできません。
編集:メニューの使用方法に関する簡単なPythonとC ++の例:
クラスが1つしかないPython:
# Using default param. here to set "action = None" or "action = toggleOpen()"
root = Menu(None, "Root directory")
snake = Menu(root, "Open snakegame", startSnakeGame)
sub1 = Menu(root, "First sub directory")
printMsg = Menu(sub1, "Print out stupid messages")
...
複数のクラスを持つPython:
# With multiple classes, action parameter no longer exists
root = DirectoryMenu(None, "Root directory")
snake = ActionMenu(root, "Open snakegame", startSnakeGame)
...
1つのクラスを持つC++:
Menu* root = new Menu(0, "Root directory");
Menu* snake = new Menu(&root, "Open snakegame", &startSnakeGame);
...
複数のクラスを持つC++:
DirectoryMenu* root = new DirectoryMenu(0, "Root directory");
ActionMenu* snake = new ActionMenu(&root, "Open snakegame", &startSnakeGame);
...
2番目の編集: Pythonでは両方の方法のみを実装し、C++では1クラスの方法のみを実装しました。それで、楽しみと練習のためだけに、C ++でもマルチクラスの方法をコーディングし始めましたが、問題が発生しました。基本クラスが1つある場合、基本クラスはを所有しておらず、基本クラスはを知ることができないため、this
親のsubMenus
-vectorに追加することはできません。subMenus
DirectoryMenu
ですから、これをハックする必要があります。これは大きなマイナスです。誰かがそれを実装するための良い方法を考えられない限り?
BaseMenu::BaseMenu(BaseMenu* parent)
: m_parent(parent) // works
{
m_parent->addSubMenuk(this); // BaseMenu doesn't have Directory's addSubMenu()
}