C++ ステート マシンの概念

Muhammad Adil 2023年10月12日
  1. C++ のステート マシンの概要
  2. ステート マシンの利点
  3. C++ での状態遷移
  4. C++ のステート マシン クラス
C++ ステート マシンの概念

このチュートリアルでは、C++ ステート マシンの概念について説明し、その使用方法を示し、その利点を強調します。

C++ のステート マシンの概要

C++ のステート マシンを理解するには、まず有限ステート マシンの概念を理解する必要があります。

有限状態マシンは、コンピューターが指定された時間に状態の有限数のいずれかになり、時間の経過とともにこれらの状態間で変化する可能性があるという考えを捉えた計算の数学モデルです。

ステート マシンは、状態、遷移、およびアクションで構成されます。 状態は、FSM が存在できるさまざまな条件です。遷移は、ある状態から別の状態への変化を引き起こすアクションです。

アクションは、FSM がある状態から別の状態に変わるときに発生します。 C++ 言語には、ステート マシンを定義する 3つのキーワード、enumswitch、および goto があります。

enum は、FSM で可能な各状態を表す一連の定数を定義します。 switch ステートメントは、アクティブな状態をチェックし、適切なアクションを実行します。

Goto は、ネストされたループからジャンプしたり、ステートメントを中断したり戻したりせずにステートメントを切り替えたりするために使用されます。

ステート マシンの利点

利点の一部を以下に示します。

  • ステート マシンは、単純な遷移規則によって複雑な動作を表現する洗練された方法を提供します。
  • 信号機、エレベーター、さらには人間の言語など、現実世界のシステムの特定の側面をモデル化するのに適しています。
  • ステート マシンは、ステート マシンの専門用語で一連のステップまたは状態に設計を分解します。 各州は特定のタスクを担当しています。
  • 対照的に、イベントは、状態マシンを状態間で移動または遷移させる刺激です。

C++ での状態遷移

C++ ステート マシン コードの状態遷移は、プログラムの状態がある状態から別の状態に変化するプロセスです。 イベントまたは条件は、トリガーと呼ばれる状態の変化をトリガーできます。

状態が変化すると、メッセージの出力や画面上のオブジェクトの色の変更など、いくつかのアクションを実行できます。

たとえば、長い間イベントがなく、その後イベントが発生した場合、waiting から default への遷移がトリガーされます。 C++ プログラミング言語では、switch ステートメントを使用してステート マシンを簡単に実装できます。

C++ のステート マシン クラス

ステート マシンを構築するときは、StateMachineEventData の 2つの基本クラスが必要です。 クラスは StateMachine から派生して、状態の変更とイベント処理をサポートするために必要なコンポーネントを取得します。

StateMachine ヘッダーには、ステート マシンの実装に役立つ複数行のプリプロセッサ マクロも含まれています。 構造体は、ステート関数に一意のデータを提供するために、EventData 基本クラスの継承者である必要があります。

ステート マシンのソース コードは、ファイル state_machine.cppdemo.h にあります。

state_machine.cpp のコード例:

#include <iostream>

#include "demo.h"
using namespace std;
void Execute_State_Machine(void) {
  int 1st_state = 0;
  while (1) {
    char trans_letter;
    cout << "1st state: " << 1st_state << "\n";
    cout << "Enter trans letter: ";
    cin >> trans_letter;
    cin.ignore(100, '\n');
    demo_Entry const* bn = demo_begin();
    demo_Entry const* const p_demo_end = demo_end();
    bool demo_um = false;
    while ((!demo_um) && (bn != p_demo_end)) {
      if (bn->1st_state_id == 1st_state) {
        if (bn->trans_letter == trans_letter) {
          cout << "changing"
               << " from 1st " << 1st_state << ", to 2nd " << bn->pro_state_id
               << "\n";
          1st_state = bn->pro_state_id;
          demo_um = true;
          break;
        }
      }
      ++bn;
    }
    if (!demo_um) {
      cerr << "same\n";
    }
  }
}

demo.h のコード例:

struct demo_x {
  int 1st_state_id;
  char trans_letter;
  int 2nd_state_id;
};
demo_x const* demo_begin(void);
demo_x const* demo_end(void);

demo.cpp のコード例:

#include "demo.h"
static const demo_x demo_m[] = {
    {0, 'T', 1},
    {0, 'U', 2},
    {0, 'V', 3},
};
static const int demo = sizeof(demo_m) / sizeof(demo_m[0]);
Table_Entry const* table_begin(void) { return &demo_m[0]; }
Table_Entry const* table_end(void) { return &demo_m[demo]; }

ここをクリック 上記のコードの動作を確認します。

著者: Muhammad Adil
Muhammad Adil avatar Muhammad Adil avatar

Muhammad Adil is a seasoned programmer and writer who has experience in various fields. He has been programming for over 5 years and have always loved the thrill of solving complex problems. He has skilled in PHP, Python, C++, Java, JavaScript, Ruby on Rails, AngularJS, ReactJS, HTML5 and CSS3. He enjoys putting his experience and knowledge into words.

Facebook