首先,我设法在单个头文件中实现状态机。我知道我需要一些前向声明,我必须从外到内定义状态。我真正不明白的是:我如何处理多个文件?
我的方法:
然后它看起来像这样:
// 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
等等。
答案 0 :(得分:2)
如果您搞砸了包含标题的顺序,则经常会出现Incomplete type
错误。
尝试以下操作:创建一个仅包含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
,因为它们不是单独的标题,只能包含和使用它们。