1) Как мне разрешить эту циклическую зависимость?
2) Я думаю, что дальнейшим шагом было бы добавить файл реализации (.cpp) для моего класса Pkt1 и передать #include "myfsm.h "к этому файлу, тем самым нарушая круговую зависимость.Но как мне переслать объявление MyFsm в заголовочном файле?
Правильно.В Pkt1.h
вы бы объявляли MyFsm
, но это просто определение типа для некоторого шаблонного типа повышения.Самым простым способом здесь является дублирование typedef (или использование) во время объявления класса, который вы используете в качестве параметра шаблона:
#include <boost/msm/back/state_machine.hpp>
struct MyFsm_;
using MyFsm = boost::msm::back::state_machine<MyFsm_>;
(Если вы используете эту часть несколько раз, вам, вероятно, следует поместить ее взаголовок, чтобы избежать дублирования кода).
Затем переместите все реализации функций в Pkt1.cpp
, сохраняя объявления в заголовке.Это работает, потому что (или пока) все ваши функции там принимают только указатели или ссылки на MyFsm
, потому что компилятору не нужно знать больше, чем «это указатель» в этой точке.
Pkt1.h
:
#include <boost/msm/back/state_machine.hpp>
struct MyFsm_;
using MyFsm = boost::msm::back::state_machine<MyFsm_>;
class Pkt1
{
public:
Pkt1() {}
void dispatch(MyFsm *fsm);
void send();
};
Pkt1.cpp
:
#include "pkt1.h"
#include "myfsm.h"
#include "events.h"
#include <iostream>
void Pkt1::dispatch(MyFsm *fsm)
{
fsm->process_event(Event1());
}
void Pkt1::send()
{
std::cout<<"pkt1 sent out ..."<<std::endl;
}
Демонстрация: https://wandbox.org/permlink/5zMsbolOMPN0biaY
3) Я новичок в boost :: msm / CRTP и код сбивает меня с толку.Как State1 может получить доступ к MyFsm, пока я не включил соответствующий заголовок для state1.h ??(может быть, потому что MyFsm происходит от внешнего / заднего конца функтора, в который включен его заголовок, и позволяет виртуальным функциям вызывать соответствующие функции MyFsm !! ??)
Ключ здесь в том, что on_entry
иon_exit
- это шаблон функций.Код для них генерируется только тогда, когда они используются - например, в реализации FSM (которая находится внутри boost, мы не можем видеть это здесь).Вот почему они должны быть в заголовке: полные тела функций должны быть видны компилятору, когда он создает (то есть генерирует код для экземпляра) шаблоны функций.В этот момент аргумент шаблона Fsm
заменяется на MyFsm
(и одно из ваших событий на Event
), так что все известно и работает.
Я бы порекомендовал прочитать о единицах перевода икак компиляторы C / C ++ генерируют код (то есть, что происходит с вашими .h
и .cpp
файлами).Как только вы это поймете, многое должно встать на свои места.