欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++ Boost MetaStateMachine定義狀態(tài)機超詳細(xì)講解

 更新時間:2022年12月07日 10:30:50   作者:無水先生  
Boost是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱。Boost庫是一個可移植、提供源代碼的C++庫,作為標(biāo)準(zhǔn)庫的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開發(fā)引擎之一,是為C++語言標(biāo)準(zhǔn)庫提供擴(kuò)展的一些C++程序庫的總稱

一、說明

Boost.MetaStateMachine 用于定義狀態(tài)機。狀態(tài)機通過對象的狀態(tài)來描述對象。它們描述了存在哪些狀態(tài)以及狀態(tài)之間可能存在哪些轉(zhuǎn)換。

Boost.MetaStateMachine 提供了三種不同的方式來定義狀態(tài)機。創(chuàng)建狀態(tài)機所需編寫的代碼取決于前端。

如果使用基本前端或函數(shù)前端,則可以用常規(guī)方式定義狀態(tài)機:創(chuàng)建類,從 Boost.MetaStateMachine 提供的其他類派生它們,定義所需的成員變量,并編寫所需的 C++自己編碼?;厩岸撕秃瘮?shù)前端的根本區(qū)別在于,基本前端需要函數(shù)指針,而函數(shù)前端讓你使用函數(shù)對象。

第三個前端稱為 eUML,它基于特定領(lǐng)域的語言。該前端可以通過重用 UML 狀態(tài)機的定義來定義狀態(tài)機。熟悉 UML 的開發(fā)人員可以將 UML 行為圖中的定義復(fù)制到 C++ 代碼。您不需要將 UML 定義轉(zhuǎn)換為 C++ 代碼。

eUML 基于您必須與此前端一起使用的一組宏。宏的優(yōu)點是您不需要直接使用 Boost.MetaStateMachine 提供的許多類。您只需要知道要使用哪些宏。這意味著您不能忘記從類派生狀態(tài)機,這可能發(fā)生在基本前端或函數(shù)前端。本章介紹使用 eUML 的 Boost.MetaStateMachine。

二、示例和代碼

示例 68.1。使用 eUML 的簡單狀態(tài)機

#include <boost/msm/front/euml/euml.hpp>
#include <boost/msm/front/euml/state_grammar.hpp>
#include <boost/msm/back/state_machine.hpp>
#include <iostream>
namespace msm = boost::msm;
using namespace boost::msm::front::euml;
BOOST_MSM_EUML_STATE((), Off)
BOOST_MSM_EUML_STATE((), On)
BOOST_MSM_EUML_EVENT(press)
BOOST_MSM_EUML_TRANSITION_TABLE((
  Off + press == On,
  On + press == Off
), light_transition_table)
BOOST_MSM_EUML_DECLARE_STATE_MACHINE(
(light_transition_table, init_ << Off),
light_state_machine)
int main()
{
  msm::back::state_machine<light_state_machine> light;
  std::cout << *light.current_state() << '\n';
  light.process_event(press);
  std::cout << *light.current_state() << '\n';
  light.process_event(press);
  std::cout << *light.current_state() << '\n';
}

Example 68.1 

示例 68.1 使用了最簡單的狀態(tài)機:一盞燈恰好有兩種狀態(tài)。它可以打開或關(guān)閉。如果它是關(guān)閉的,它可以被打開。如果已打開,則可以將其關(guān)閉??梢詮拿總€狀態(tài)切換到每個其他狀態(tài)。

示例 68.1 使用 eUML 前端來描述燈的狀態(tài)機。 Boost.MetaStateMachine 沒有主頭文件。因此,必須將需要的頭文件一一包含進(jìn)來。 boost/msm/front/euml/euml.hpp 和 boost/msm/front/euml/state_grammar.hpp 提供對 eUML 宏的訪問。 boost/msm/back/state_machine.hpp 需要將前端的狀態(tài)機鏈接到后端的狀態(tài)機。雖然前端提供了定義狀態(tài)機的各種可能性,但狀態(tài)機的實際實現(xiàn)是在后端找到的。由于 Boost.MetaStateMachine 僅包含一個后端,因此您無需選擇實現(xiàn)。

Boost.MetaStateMachine 中的所有定義都在命名空間 boost::msm 中。不幸的是,許多 eUML 宏并沒有明確引用這個命名空間中的類。他們使用命名空間 msm 或根本不使用命名空間。這就是為什么示例 68.1 為命名空間 boost::msm 創(chuàng)建了一個別名,并使 boost::msm::front::euml 中的定義可用于 using 指令。否則 eUML 宏會導(dǎo)致編譯器錯誤。

要使用燈的狀態(tài)機,首先要定義關(guān)和開的狀態(tài)。狀態(tài)是用宏 BOOST_MSM_EUML_STATE 定義的,它需要狀態(tài)的名稱作為它的第二個參數(shù)。第一個參數(shù)描述狀態(tài)。稍后你會看到這些描述是什么樣子的。示例 68.1 中定義的兩個狀態(tài)稱為關(guān)閉和打開。

要在狀態(tài)之間切換,需要事件。事件是用宏 BOOST_MSM_EUML_EVENT 定義的,它期望事件的名稱作為其唯一參數(shù)。示例 68.1 定義了一個名為 press 的事件,它表示按下電燈開關(guān)的動作。由于同一事件會打開和關(guān)閉一盞燈,因此只定義了一個事件。

定義所需的狀態(tài)和事件后,宏 BOOST_MSM_EUML_TRANSITION_TABLE 用于創(chuàng)建轉(zhuǎn)換表。該表定義了狀態(tài)之間的有效轉(zhuǎn)換以及哪些事件觸發(fā)了哪些狀態(tài)轉(zhuǎn)換。

BOOST_MSM_EUML_TRANSITION_TABLE 需要兩個參數(shù)。第一個參數(shù)定義了轉(zhuǎn)換表,第二個是轉(zhuǎn)換表的名稱。第一個參數(shù)的語法旨在使識別狀態(tài)和事件如何相互關(guān)聯(lián)變得容易。例如,Off + press == On 表示處于 Off 狀態(tài)的機器通過按下事件切換到 On 狀態(tài)。轉(zhuǎn)換表定義的直觀和不言自明的語法是 eUML 前端的優(yōu)勢之一。

創(chuàng)建轉(zhuǎn)換表后,使用宏 BOOST_MSM_EUML_DECLARE_STATE_MACHINE 定義狀態(tài)機。第二個參數(shù)也是更簡單的一個:它設(shè)置狀態(tài)機的名稱。示例 68.1 中的狀態(tài)機名為 light_state_machine。

BOOST_MSM_EUML_DECLARE_STATE_MACHINE 的第一個參數(shù)是一個元組。第一個值是轉(zhuǎn)換表的名稱。第二個值是一個使用 init_ 的表達(dá)式,它是 Boost.MetaStateMachine 提供的一個屬性。稍后您將了解有關(guān)屬性的更多信息。需要表達(dá)式 init_ << Off 將狀態(tài)機的初始狀態(tài)設(shè)置為 Off。

用 BOOST_MSM_EUML_DECLARE_STATE_MACHINE 定義的狀態(tài)機 light_state_machine 是一個類。您使用此類從后端實例化狀態(tài)機。在示例 68.1 中,這是通過將 light_state_machine 作為參數(shù)傳遞給類模板 boost::msm::back::state_machine 來完成的。這會創(chuàng)建一個名為 light 的狀態(tài)機。

狀態(tài)機提供一個成員函數(shù) process_event() 來處理事件。如果您將事件傳遞給 process_event(),狀態(tài)機會根據(jù)其轉(zhuǎn)換表更改其狀態(tài)。

為了更容易看到多次調(diào)用 process_event() 時示例 68.1 中發(fā)生的情況,調(diào)用了 current_state()。此成員函數(shù)應(yīng)僅用于調(diào)試目的。它返回一個指向 int 的指針。每個狀態(tài)都是一個 int 值,按照狀態(tài)在 BOOST_MSM_EUML_TRANSITION_TABLE 中被訪問的順序分配。在示例 68.1 中,Off 被賦予值 0,而 On 被賦予值 1。該示例將 0、1 和 0 寫入標(biāo)準(zhǔn)輸出。按下燈開關(guān)兩次,可以打開和關(guān)閉燈。

示例 68.2。具有狀態(tài)、事件和動作的狀態(tài)機

#include <boost/msm/front/euml/euml.hpp>
#include <boost/msm/front/euml/state_grammar.hpp>
#include <boost/msm/back/state_machine.hpp>
#include <iostream>
namespace msm = boost::msm;
using namespace boost::msm::front::euml;
BOOST_MSM_EUML_STATE((), Off)
BOOST_MSM_EUML_STATE((), On)
BOOST_MSM_EUML_EVENT(press)
BOOST_MSM_EUML_ACTION(switch_light)
{
  template <class Event, class Fsm>
  void operator()(const Event &ev, Fsm &fsm,
    BOOST_MSM_EUML_STATE_NAME(Off) &sourceState,
    BOOST_MSM_EUML_STATE_NAME(On) &targetState) const
  {
    std::cout << "Switching on\n";
  }
  template <class Event, class Fsm>
  void operator()(const Event &ev, Fsm &fsm,
    decltype(On) &sourceState,
    decltype(Off) &targetState) const
  {
    std::cout << "Switching off\n";
  }
};
BOOST_MSM_EUML_TRANSITION_TABLE((
  Off + press / switch_light == On,
  On + press / switch_light == Off
), light_transition_table)
BOOST_MSM_EUML_DECLARE_STATE_MACHINE(
(light_transition_table, init_ << Off),
light_state_machine)
int main()
{
  msm::back::state_machine<light_state_machine> light;
  light.process_event(press);
  light.process_event(press);
}

Example 68.2 

示例 68.2 通過一個動作擴(kuò)展了燈的狀態(tài)機。動作由觸發(fā)狀態(tài)轉(zhuǎn)換的事件執(zhí)行。因為動作是可選的,所以可以在沒有它們的情況下定義狀態(tài)機。

操作是使用 BOOST_MSM_EUML_ACTION 定義的。嚴(yán)格來說,定義了一個函數(shù)對象。您必須重載運算符 operator()。操作員必須接受四個參數(shù)。參數(shù)引用一個事件、一個狀態(tài)機和兩個狀態(tài)。您可以自由定義模板或為所有參數(shù)使用具體類型。在示例 68.2 中,僅為最后兩個參數(shù)設(shè)置具體類型。因為這些參數(shù)描述了開始和結(jié)束狀態(tài),所以您可以重載 operator() 以便為不同的開關(guān)執(zhí)行不同的成員函數(shù)。

請注意狀態(tài) On 和 Off 是對象。 Boost.MetaStateMachine 提供了一個宏 BOOST_MSM_EUML_STATE_NAME 來獲取狀態(tài)的類型。如果您使用 C++11,則可以使用運算符 decltype 而不是宏。

switch_light 動作已通過 BOOST_MSM_EUML_ACTION 定義,在按下燈開關(guān)時執(zhí)行。轉(zhuǎn)換表已相應(yīng)更改。第一個轉(zhuǎn)換現(xiàn)在是 Off + press / switch_light == On。您在事件后的斜線后傳遞操作。此轉(zhuǎn)換意味著如果當(dāng)前狀態(tài)為 Off 并且事件按下發(fā)生,則調(diào)用 switch_light 的運算符 operator()。執(zhí)行操作后,新狀態(tài)為開啟。

示例 68.2 將 Switching on 然后 Switching off 寫入標(biāo)準(zhǔn)輸出。

示例 68.3。具有狀態(tài)、事件、守衛(wèi)和動作的狀態(tài)機

#include <boost/msm/front/euml/euml.hpp>
#include <boost/msm/front/euml/state_grammar.hpp>
#include <boost/msm/back/state_machine.hpp>
#include <iostream>
namespace msm = boost::msm;
using namespace boost::msm::front::euml;
BOOST_MSM_EUML_STATE((), Off)
BOOST_MSM_EUML_STATE((), On)
BOOST_MSM_EUML_EVENT(press)
BOOST_MSM_EUML_ACTION(is_broken)
{
  template <class Event, class Fsm, class Source, class Target>
  bool operator()(const Event &ev, Fsm &fsm, Source &src, Target &trg) const
  {
    return true;
  }
};
BOOST_MSM_EUML_ACTION(switch_light)
{
  template <class Event, class Fsm, class Source, class Target>
  void operator()(const Event &ev, Fsm &fsm, Source &src, Target &trg) const
  {
    std::cout << "Switching\n";
  }
};
BOOST_MSM_EUML_TRANSITION_TABLE((
  Off + press [!is_broken] / switch_light == On,
  On + press / switch_light == Off
), light_transition_table)
BOOST_MSM_EUML_DECLARE_STATE_MACHINE(
(light_transition_table, init_ << Off),
light_state_machine)
int main()
{
  msm::back::state_machine<light_state_machine> light;
  light.process_event(press);
  light.process_event(press);
}

Example 68.3 

示例 68.3 在轉(zhuǎn)換表中使用了一個守衛(wèi)。第一個轉(zhuǎn)換的定義是 Off + press [!is_broken] / switch_light == On。在括號中傳遞 is_broken 意味著狀態(tài)機在調(diào)用動作 switch_light 之前檢查是否可能發(fā)生轉(zhuǎn)換。這叫做守衛(wèi)。守衛(wèi)必須返回布爾類型的結(jié)果。

像 is_broken 這樣的守衛(wèi)是用 BOOST_MSM_EUML_ACTION 定義的,其方式與動作相同。因此,必須為相同的四個參數(shù)重載運算符 operator()。 operator() 必須有一個 bool 類型的返回值才能用作守衛(wèi)。

請注意,您可以使用運算符等邏輯運算符!在括號內(nèi)的守衛(wèi)上。

如果運行該示例,您會注意到?jīng)]有任何內(nèi)容寫入標(biāo)準(zhǔn)輸出。 switch_light 動作未執(zhí)行 - 燈保持關(guān)閉狀態(tài)。守衛(wèi) is_broken 返回 true。但是,因為運算符運算符!使用時,括號中的表達(dá)式的計算結(jié)果為 false。

您可以使用守衛(wèi)來檢查是否可以發(fā)生狀態(tài)轉(zhuǎn)換。示例 68.3 使用 is_broken 檢查燈是否壞了。雖然從關(guān)閉到打開的轉(zhuǎn)換通常是可能的,并且轉(zhuǎn)換表正確地描述了燈,但在此示例中,燈無法打開。盡管調(diào)用了兩次 process_event(),但燈的狀態(tài)為關(guān)閉。

示例 68.4。具有狀態(tài)、事件、進(jìn)入動作和退出動作的狀態(tài)機

#include <boost/msm/front/euml/euml.hpp>
#include <boost/msm/front/euml/state_grammar.hpp>
#include <boost/msm/back/state_machine.hpp>
#include <iostream>
namespace msm = boost::msm;
using namespace boost::msm::front::euml;
BOOST_MSM_EUML_ACTION(state_entry)
{
  template <class Event, class Fsm, class State>
  void operator()(const Event &ev, Fsm &fsm, State &state) const
  {
    std::cout << "Entering\n";
  }
};
BOOST_MSM_EUML_ACTION(state_exit)
{
  template <class Event, class Fsm, class State>
  void operator()(const Event &ev, Fsm &fsm, State &state) const
  {
    std::cout << "Exiting\n";
  }
};
BOOST_MSM_EUML_STATE((state_entry, state_exit), Off)
BOOST_MSM_EUML_STATE((state_entry, state_exit), On)
BOOST_MSM_EUML_EVENT(press)
BOOST_MSM_EUML_TRANSITION_TABLE((
  Off + press == On,
  On + press == Off
), light_transition_table)
BOOST_MSM_EUML_DECLARE_STATE_MACHINE(
(light_transition_table, init_ << Off),
light_state_machine)
int main()
{
  msm::back::state_machine<light_state_machine> light;
  light.process_event(press);
  light.process_event(press);
}

在示例 68.4 中,傳遞給 BOOST_MSM_EUML_STATE 的第一個參數(shù)是一個由 state_entry 和 state_exit 組成的元組。 state_entry 是進(jìn)入動作,state_exit 是退出動作。這些動作在進(jìn)入或退出狀態(tài)時執(zhí)行。

與操作一樣,進(jìn)入和退出操作是使用 BOOST_MSM_EUML_ACTION 定義的。但是,重載運算符 operator() 只需要三個參數(shù):對事件的引用、狀態(tài)機和狀態(tài)。狀態(tài)之間的轉(zhuǎn)換對于進(jìn)入和退出操作無關(guān)緊要,因此只需將一個狀態(tài)傳遞給 operator()。對于進(jìn)入動作,進(jìn)入該狀態(tài)。對于退出操作,此狀態(tài)已退出。

在示例 68.4 中,狀態(tài) Off 和 On 都有進(jìn)入和退出操作。因為事件按下發(fā)生了兩次,所以 Entering 和 Exiting 顯示了兩次。請注意,Exiting 會先顯示,Entering 會顯示在后面,因為執(zhí)行的第一個操作是退出操作。

第一個事件按下觸發(fā)從關(guān)閉到開啟的轉(zhuǎn)換,退出和進(jìn)入各顯示一次。第二次事件按下將狀態(tài)切換為關(guān)閉。 Exiting 和 Entering 再次顯示一次。因此,狀態(tài)轉(zhuǎn)換首先執(zhí)行退出動作,然后執(zhí)行新狀態(tài)的進(jìn)入動作。

示例 68.5。狀態(tài)機中的屬性

#include <boost/msm/front/euml/euml.hpp>
#include <boost/msm/front/euml/state_grammar.hpp>
#include <boost/msm/back/state_machine.hpp>
#include <iostream>
namespace msm = boost::msm;
using namespace boost::msm::front::euml;
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int, switched_on)
BOOST_MSM_EUML_ACTION(state_entry)
{
  template <class Event, class Fsm, class State>
  void operator()(const Event &ev, Fsm &fsm, State &state) const
  {
    std::cout << "Switched on\n";
    ++fsm.get_attribute(switched_on);
  }
};
BOOST_MSM_EUML_ACTION(is_broken)
{
  template <class Event, class Fsm, class Source, class Target>
  bool operator()(const Event &ev, Fsm &fsm, Source &src, Target &trg) const
  {
    return fsm.get_attribute(switched_on) > 1;
  }
};
BOOST_MSM_EUML_STATE((), Off)
BOOST_MSM_EUML_STATE((state_entry), On)
BOOST_MSM_EUML_EVENT(press)
BOOST_MSM_EUML_TRANSITION_TABLE((
  Off + press [!is_broken] == On,
  On + press == Off
), light_transition_table)
BOOST_MSM_EUML_DECLARE_STATE_MACHINE(
(light_transition_table, init_ << Off, no_action, no_action,
attributes_ << switched_on), light_state_machine)
int main()
{
  msm::back::state_machine<light_state_machine> light;
  light.process_event(press);
  light.process_event(press);
  light.process_event(press);
  light.process_event(press);
  light.process_event(press);
}

Example 68.5 

示例 68.5 使用守衛(wèi) is_broken 檢查是否可以從 Off 到 On 的狀態(tài)轉(zhuǎn)換。這次 is_broken 的返回值取決于電燈開關(guān)被按下的頻率??梢栽跓魤闹皩舸蜷_兩次。為了計算燈打開的頻率,使用了一個屬性。

屬性是可以附加到對象的變量。它們允許您在運行時調(diào)整狀態(tài)機的行為。因為諸如開燈頻率之類的數(shù)據(jù)必須存儲在某個地方,所以將其直接存儲在狀態(tài)機、狀態(tài)或事件中是有意義的。

在使用屬性之前,必須對其進(jìn)行定義。這是通過宏 BOOST_MSM_EUML_DECLARE_ATTRIBUTE 完成的。傳遞給 BOOST_MSM_EUML_DECLARE_ATTRIBUTE 的第一個參數(shù)是類型,第二個是屬性的名稱。示例 68.5 定義了 int 類型的屬性 switched_on。

定義屬性后,必須將其附加到對象。該示例將屬性 switched_on 附加到狀態(tài)機。這是通過元組中的第五個值完成的,該值作為第一個參數(shù)傳遞給 BOOST_MSM_EUML_DECLARE_STATE_MACHINE。使用 attributes_,來自 Boost.MetaStateMachine 的關(guān)鍵字用于創(chuàng)建 lambda 函數(shù)。要將屬性 switched_on 附加到狀態(tài)機,請使用 operator<< 將 switched_on 寫入 attributes_,就好像它是一個流一樣。

元組中的第三個和第四個值都設(shè)置為 no_action。該屬性作為元組中的第五個值傳遞。第三個和第四個值可用于定義狀態(tài)機的進(jìn)入和退出操作。如果沒有定義進(jìn)入和退出操作,請使用 no_action。

將屬性附加到狀態(tài)機后,可以使用 get_attribute() 訪問它。在示例 68.5 中,此成員函數(shù)在入口操作 state_entry 中被調(diào)用以增加屬性的值。因為 state_entry 僅鏈接到狀態(tài) On,switched_on 僅在燈打開時遞增。

switched_on 也可以從守衛(wèi) is_broken 訪問,它檢查屬性的值是否大于 1。如果是,守衛(wèi)返回 true。由于屬性是使用默認(rèn)構(gòu)造函數(shù)初始化的,并且 switched_on 設(shè)置為 0,如果燈已打開兩次,is_broken 將返回 true。

在示例 68.5 中,事件按下發(fā)生了五次。燈被打開和關(guān)閉兩次,然后再次打開。燈打開的前兩次會顯示“已打開”。但是,第三次打開燈時沒有輸出。發(fā)生這種情況是因為 is_broken 在燈被打開兩次后返回 true,因此,沒有從 Off 到 On 的狀態(tài)轉(zhuǎn)換。這意味著不執(zhí)行狀態(tài) On 的進(jìn)入操作,并且該示例不寫入標(biāo)準(zhǔn)輸出。

示例 68.6。訪問轉(zhuǎn)換表中的屬性

#include <boost/msm/front/euml/euml.hpp>
#include <boost/msm/front/euml/state_grammar.hpp>
#include <boost/msm/back/state_machine.hpp>
#include <iostream>
namespace msm = boost::msm;
using namespace boost::msm::front::euml;
BOOST_MSM_EUML_DECLARE_ATTRIBUTE(int, switched_on)
void write_message()
{
  std::cout << "Switched on\n";
}
BOOST_MSM_EUML_FUNCTION(WriteMessage_, write_message, write_message_,
  void, void)
BOOST_MSM_EUML_STATE((), Off)
BOOST_MSM_EUML_STATE((), On)
BOOST_MSM_EUML_EVENT(press)
BOOST_MSM_EUML_TRANSITION_TABLE((
  Off + press [fsm_(switched_on) < Int_<2>()] / (++fsm_(switched_on),
    write_message_()) == On,
  On + press == Off
), light_transition_table)
BOOST_MSM_EUML_DECLARE_STATE_MACHINE(
(light_transition_table, init_ << Off, no_action, no_action,
attributes_ << switched_on), light_state_machine)
int main()
{
  msm::back::state_machine<light_state_machine> light;
  light.process_event(press);
  light.process_event(press);
  light.process_event(press);
  light.process_event(press);
  light.process_event(press);
}

Example 68.6 

示例 68.6 與示例 68.5 做同樣的事情:將燈打開兩次后,燈壞了,無法再打開。雖然前面的示例在操作中訪問了 switched_on 屬性,但此示例使用轉(zhuǎn)換表中的屬性。

Boost.MetaStateMachine 提供函數(shù) fsm_() 來訪問狀態(tài)機中的屬性。這樣就定義了一個守衛(wèi)來檢查 switched_on 是否小于 2。并且定義了一個動作,每次狀態(tài)從 Off 切換到 On 時都會增加 switched_on。

請注意,守衛(wèi)中的小于比較是通過 Int_<2>() 完成的。數(shù)字 2 必須作為模板參數(shù)傳遞給 Int_ 以創(chuàng)建此類的實例。這將創(chuàng)建一個具有 Boost.MetaStateMachine 所需類型的函數(shù)對象。

示例 68.6 還使用宏 BOOST_MSM_EUML_FUNCTION 使函數(shù)成為動作。傳遞給 BOOST_MSM_EUML_FUNCTION 的第一個參數(shù)是可以在函數(shù)前端使用的動作的名稱。第二個參數(shù)是函數(shù)的名稱。第三個參數(shù)是在 eUML 中使用的操作名稱。第四個和第五個參數(shù)是函數(shù)的返回值——一個用于動作用于狀態(tài)轉(zhuǎn)換的情況,另一個用于動作描述進(jìn)入或退出動作的情況。以這種方式將 write_message() 轉(zhuǎn)換為動作后,將在轉(zhuǎn)換表中的 ++fsm_(switched_on) 之后創(chuàng)建并使用 write_message_ 類型的對象。在從 Off 到 On 的狀態(tài)轉(zhuǎn)換中,屬性 switched_on 遞增,然后調(diào)用 write_message()。

Example 68.6 

與示例 68.5 中一樣,示例 68.6 顯示兩次打開。

Boost.MetaStateMachine 提供額外的函數(shù),例如 state_() 和 event_(),以訪問附加到其他對象的屬性。其他類,例如 Char_ 和 String_,也可以像 Int_ 一樣使用。

提示

正如您在示例中看到的,前端 eUML 要求您使用許多宏。頭文件 boost/msm/front/euml/common.hpp 包含所有 eUML 宏的定義,這使其成為一個有用的參考。

練習(xí)

為可以關(guān)閉、打開或傾斜的窗口創(chuàng)建狀態(tài)機。關(guān)閉的窗戶可以打開或傾斜。如果不先關(guān)閉打開的窗戶,則無法傾斜它。傾斜的窗戶也不能在不先關(guān)閉的情況下打開。通過打開和傾斜您的窗口幾次來測試您的狀態(tài)機。使用 current_state() 將狀態(tài)寫入標(biāo)準(zhǔn)輸出。

擴(kuò)展?fàn)顟B(tài)機:窗戶應(yīng)該是智能家居的一部分。狀態(tài)機現(xiàn)在應(yīng)該計算窗戶打開和傾斜的頻率。要測試您的狀態(tài)機,請打開并傾斜您的窗口幾次。在程序結(jié)束時,將窗口打開的頻率和傾斜的頻率寫入標(biāo)準(zhǔn)輸出。

到此這篇關(guān)于C++ Boost MetaStateMachine定義狀態(tài)機超詳細(xì)講解的文章就介紹到這了,更多相關(guān)C++ Boost MetaStateMachine內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • OpenCV4.1.0+VisualStudio2019開發(fā)環(huán)境搭建(超級簡單)

    OpenCV4.1.0+VisualStudio2019開發(fā)環(huán)境搭建(超級簡單)

    這篇文章主要介紹了OpenCV4.1.0+VisualStudio2019開發(fā)環(huán)境搭建(超級簡單),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • C語言數(shù)據(jù)結(jié)構(gòu)之線索二叉樹及其遍歷

    C語言數(shù)據(jù)結(jié)構(gòu)之線索二叉樹及其遍歷

    這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)之線索二叉樹及其遍歷的相關(guān)資料,為了加快查找節(jié)點的前驅(qū)和后繼。對二叉樹的線索化就是對二叉樹進(jìn)行一次遍歷,在遍歷的過程中檢測節(jié)點的左右指針是否為空,如果是空,則將他們改為指向前驅(qū)和后繼節(jié)點的線索,需要的朋友可以參考下
    2017-08-08
  • C++的std::transform()的實現(xiàn)

    C++的std::transform()的實現(xiàn)

    在 C++ 標(biāo)準(zhǔn)庫中,std::transform() 是一個非常有用的算法函數(shù),它能夠?qū)⒔o定范圍中的每個元素進(jìn)行變換,并將變換后的結(jié)果存儲到另一個范圍中,本文就詳細(xì)的介紹一下具體用法,感興趣的可以了解一下
    2023-08-08
  • C++獲取MD5算法實現(xiàn)代碼

    C++獲取MD5算法實現(xiàn)代碼

    這篇文章主要介紹了C++獲取MD5算法實現(xiàn)代碼,這個是網(wǎng)上扒下來的 作者已經(jīng)無法知道是誰了 ,可以備用
    2019-04-04
  • c++ 獲取數(shù)字字符串的子串?dāng)?shù)值性能示例分析

    c++ 獲取數(shù)字字符串的子串?dāng)?shù)值性能示例分析

    這篇文章主要為大家介紹了c++ 獲取數(shù)字字符串的子串?dāng)?shù)值示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • QT實現(xiàn)單詞檢索軟件的示例代碼

    QT實現(xiàn)單詞檢索軟件的示例代碼

    本文主要介紹了QT實現(xiàn)單詞檢索軟件的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 利用Qt+opencv實現(xiàn)視頻分解為圖片

    利用Qt+opencv實現(xiàn)視頻分解為圖片

    這篇文章主要為大家詳細(xì)介紹了如何利用Qt和opencv實現(xiàn)視頻分解為圖片,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-12-12
  • 如何基于 Blueprint 在游戲中創(chuàng)建實時音視頻功能

    如何基于 Blueprint 在游戲中創(chuàng)建實時音視頻功能

    我們在本文先來講講如何在 Unreal 中用 Blueprint 快速實現(xiàn)。稍后會分享基于 C++的實現(xiàn)步驟。感興趣的朋友跟隨小編一起看看吧
    2020-05-05
  • C/C++?Qt?TableDelegate?自定義代理組件使用詳解

    C/C++?Qt?TableDelegate?自定義代理組件使用詳解

    TableDelegate自定義代理組件的主要作用是對原有表格進(jìn)行調(diào)整,本文主要介紹了QT中TableDelegate?自定義代理組件的使用教程,感興趣的朋友可以了解一下
    2021-12-12
  • EasyX繪制透明背景圖的方法詳解

    EasyX繪制透明背景圖的方法詳解

    這篇文章主要為大家詳細(xì)介紹了EasyX繪制透明背景圖的方法,文中的示例代碼講解詳細(xì),對我們深入了解EasyX有一定的幫助,需要的可以參考一下
    2023-01-01

最新評論