【问题标题】:State machines without default constructors in boost:msmboost:msm 中没有默认构造函数的状态机
【发布时间】:2015-06-18 08:15:04
【问题描述】:

在 boost::msm 的文档中,有一个状态机的 example 没有默认构造函数。我可以让它在我直接从超级 SM 跳到子 SM 的地方工作。但是当我从一个子 SM 跳到另一个子 SM 时,目标 SM 是默认构造的,我的数据就消失了。 下面是一个例子。如果不为子状态提供默认构造函数,我无法编译它。我是否需要在我的子 SM 中提供一些额外的信息才能使其正常工作?

当我运行示例时,我得到:

Jumping directly to Sub1
Sub1.data_ = 0x7fff5fbfd778
Jumping directly to Sub2
Sub2.data_ = 0x7fff5fbfd778
Jumping from Sub1 to Sub2
Sub1.data_ = 0x7fff5fbfd778
Sub2.data_ = 0xdeadbeef

我希望 0xdeadbeef 与其他地址相同。

#include <iostream>
#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>

namespace {

    using namespace boost::msm;
    using namespace boost::msm::front;
    namespace mpl = boost::mpl;

    struct MyData {
        int data;
    };

    struct EvGotoSub1 {};
    struct EvGotoSub2 {};

    struct MainSM_;
    using Main = back::state_machine<MainSM_>;    
    struct Sub1SM_;
    using Sub1 = back::state_machine<Sub1SM_>;
    struct Sub2SM_;
    using Sub2 = back::state_machine<Sub2SM_>;

    struct Sub1SM_ : state_machine_def<Sub1SM_> {
        struct Started : state<> {
            template <class Event,class Fsm>
            void on_entry(Event const& e, Fsm& fsm) {
                std::cout << "Sub1.data_ = " << (void*) fsm.data_ << std::endl;
            }
        };
        using initial_state = mpl::vector<Started>;
        struct transition_table:mpl::vector<
        Row<Started, EvGotoSub2, Sub2, none, none>
        > {};
        MyData* data_;

        Sub1SM_() : data_((MyData*) 0xdeadbeef) {};
        Sub1SM_(MyData* data) : data_(data) {};
    };

    struct Sub2SM_ : state_machine_def<Sub2SM_> {
        struct Started : state<> {
            template <class Event,class Fsm>
            void on_entry(Event const& e, Fsm& fsm) {
                std::cout << "Sub2.data_ = " << (void*) fsm.data_ << std::endl;
            }
        };
        using initial_state = mpl::vector<Started>;
        struct transition_table:mpl::vector<
        //Row<Started, EvGotoSub1, Sub1, none, none>
        > {};
        MyData* data_;

        Sub2SM_() : data_((MyData*) 0xdeadbeef) {};
        Sub2SM_(MyData* data) : data_(data) {};
    };

    struct MainSM_ : state_machine_def<MainSM_> {
        struct Started : state<> {};
        using initial_state = mpl::vector<Started>;
        struct transition_table:mpl::vector<
        Row<Started, EvGotoSub1, Sub1, none, none>,
        Row<Started, EvGotoSub2, Sub2, none, none>
        > {};
        MyData* data_;

        MainSM_(MyData* data) : data_(data) {};
    };
}

int main() {
    MyData data { 123 };

    auto CreateMain = [&data] {
        auto ret = Main(back::states_ << Sub1(&data) << Sub2(&data), &data);
        ret.start();
        return ret;
    };

    std::cout << "Jumping directly to Sub1" << std::endl;
    Main main = CreateMain();
    main.process_event(EvGotoSub1());

    std::cout << "Jumping directly to Sub2" << std::endl;
    main = CreateMain();
    main.process_event(EvGotoSub2());

    std::cout << "Jumping from Sub1 to Sub2" << std::endl;
    main = CreateMain();
    main.process_event(EvGotoSub1());
    main.process_event(EvGotoSub2());        
}

【问题讨论】:

    标签: c++ boost-msm


    【解决方案1】:

    必须定义默认构造函数。 对于Sub1,您还必须指定要使用Sub2 的哪个构造函数:

    auto ret = Main(back::states_ << Sub1(back::states_ << Sub2(&data), &data) << Sub2(&data), &data);
    

    这个输出:

    Jumping directly to Sub1
    Sub1.data_ = 0xbfe82bf0
    Jumping directly to Sub2
    Sub2.data_ = 0xbfe82bf0
    Jumping from Sub1 to Sub2
    Sub1.data_ = 0xbfe82bf0
    Sub2.data_ = 0xbfe82bf0
    

    实时示例:https://ideone.com/XMtDye

    【讨论】:

      猜你喜欢
      • 2023-03-20
      • 2016-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-19
      • 2021-09-04
      相关资源
      最近更新 更多