Наследовать реакции
Я хотел бы определить базовый класс, производный от statechart::simple_state
, которая имеет "предопределенные" реакции, которые сами вызывают виртуальные функции (которые должны быть реализованы в производных классах). Я хотел бы, чтобы некоторые состояния автоматически реагировали на определенные события, если они происходят из моего базового класса.
Как это (sc
является boost::statechart
):
struct EvHeartBeat : sc::event<EvHeartBeat> {};
template< class MostDerived,
class Context,
class InnerInitial = boost::mpl::list<>,
sc::history_mode historyMode = sc::has_no_history >
class BaseState : public sc::simple_state<
MostDerived, Context, InnerInitial, historyMode >
{
public:
typedef sc::custom_reaction<EvHeartBeat> reactions;
sc::result react (const EvHeartBeat& )
{
// maybe check some conditions here ...
return react_heartbeat();
}
protected:
virtual sc::result react_heartbeat() = 0;
};
Затем в производном классе:
struct MyState :
BaseState<MyState, MyChart>
{
// there are also other reactions
typedef sc::custom_reaction<OtherEvent> reactions;
sc::result react_heartbeat()
{
std::cout << "foo" << std::endl;
}
sc::result react (const OtherEvent&) { /* ... */ }
};
typedef
в производном классе будет "перезаписывать" тот, который я предполагаю в базовом классе, поэтому, возможно, мне нужно определить custon_reaction
к сердцебиению как список в производном классе. Но, может быть, этот дизайн не такой, как думали дизайнеры этой библиотеки, кто-нибудь, кто может мне помочь с этим?
РЕДАКТИРОВАТЬ
Тем временем я получил некоторые дополнительные знания. Обходной путь для typedef
было бы просто определить его в производном классе вместо базового класса. Но тогда возникает странная проблема: компилятор не найдет метод для react (const EvHeartBeat& )
хотя это определено в базовом классе, если я удалю другую реакцию (react (const OtherEvent& )
) оно работает. Но, конечно, это не то, что я хочу, я хочу иметь возможность реагировать на несколько событий.
1 ответ
Я спросил это также на boost-users
мл и получил ответ, который очень помог. Проблема в том, что определение метода в подклассе затеняет определение в родительском классе, хотя список параметров отличается (OtherEvent
против EvHeartBeat
). Решение состоит в том, чтобы явно повторно использовать метод из суперкласса:
using BaseState::react;
result react ( const OtherEvent& );
Этот работает так, как должен.