Наследовать реакции

Я хотел бы определить базовый класс, производный от 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& );

Этот работает так, как должен.

Другие вопросы по тегам