提升状态图:如何跨多个文件传播?

时间:2013-01-18 08:32:16

标签: c++ boost

首先,我设法在单个头文件中实现状态机。我知道我需要一些前向声明,我必须从外到内定义状态。我真正不明白的是:我如何处理多个文件?

我的方法:

  • 每个州一个标题
  • 一个标题包含所有可能的状态,前向声明
  • 声明状态的每个标头包括声明其上下文的标头

然后它看起来像这样:

// forward.h
struct Machine;
struct StA;
struct StB;

// machine.h
#include "forward.h"
struct Machine : sc::state_machine< Machine, StA > {};

// a.h
#include "forward.h" // for StB
#include "machine.h"
struct StA : sc::simple_state< StA, Machine, StB > {};

// b.h
#include "forward.h"
#include "a.h"
struct StB : sc::simple_state< StB, StA > {};

现在,如何在程序中包含整个内容。我的想法是有一个标题,从外到内包括所有州的标题。

// the_machine.h
#include "forward.h"
#include "machine.h"
#include "a.h"
#include "b.h"

// use this header now where you need the state machine

但是,我不知道一般的想法是否正常,即使如此,我也无法进行编译(好吧,不是完全这个,而是我按照这个设计构建的机器原理)。将所有内容放在一个文件中,一旦确定上下文需要完成,状态需要向前声明等等,但是由于复杂性和维护原因的分裂会让我神经紧张...... Incomplete type 'StXY' used in nested name specifier等等。

1 个答案:

答案 0 :(得分:2)

如果您搞砸了包含标题的顺序,则经常会出现Incomplete type错误。

  • 您是否在头文件中使用了正确的包含警戒?
  • 当你有圆形包含时,有时前向声明会搞砸。
  • 有时会复制一个标题以生成类似的标题(例如a.h和b.h)并忘记更改包含警戒。这可能很难追查。

尝试以下操作:创建一个仅包含the_machine.h的空.cpp,并仅对其进行预编译。编写包含预处理翻译单元的文件的不同编译器有命令行标志(即一个文件包含编译器可以看到的所有代码)。检查该文件以查看是否所有内容都按照您认为的顺序排列。大多数预处理器生成#line个控制命令,告诉编译器(和你)你正在查看哪个标题/源代码行。

修改

如果您只想#include machine.h,则必须在机器定义之后包含状态定义。乍一看可能看起来很奇怪,但如果你想分割相关部分,这就是它一般适用于模板的方式。许多人为后面包含的部分使用不同的文件后缀,因为它们本身并不是真正的标题,即你不能单独包含它们。例如:

//Something.h
template <class T>
struct Something
{
   void meow(T const& t);
   int wuff(T const& t, int b);
};

#include "Something.impl" //or .ipp, or other endings...

//Something.impl
template <class T>
void Something<T>::meow(T const& t)
{ /* implement... */ }

template <class T>
int Something<T>::wuff(T const& t, int b)
{ /* implement... */ }

您的machine.h看起来很相似 - 定义机器并在其后包含状态的实现。我不会说出州的实施文件X.h,因为它们不是单独的标题,只能包含和使用它们。