1

まず、1 つのヘッダー ファイルにステート マシンを実装することに成功しました。いくつかの前方宣言が必要であることはわかっており、外側から内側への状態を定義する必要があります。私が本当に理解していないのは、複数のファイルでこれを行うにはどうすればよいですか?

私のアプローチ:

  • 状態ごとに 1 つのヘッダー
  • 可能なすべての状態を含む 1 つのヘッダー、前方宣言
  • 状態を宣言する各ヘッダーには、そのコンテキストを宣言するヘッダーが含まれます

次に、次のようになります。

// 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 > {};

現在、すべてをプログラムに含める方法は未解決のままです。私のアイデアは、すべての州のヘッダーの外側から内側までを含む 1 つのヘッダーを持つことでした。

// 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

ただし、一般的なアイデアが正しいかどうかはわかりません。たとえそうであったとしても、これをコンパイルすることはできません (正確にはこれではなく、この設計原則に従って構築したマシンです)。コンテキストを完全にする必要があること、状態を事前に宣言する必要があることなどに気付いたら、すべてを1つのファイルにまとめるのは非常に簡単ですが、複雑さとメンテナンスの理由で分割すると神経がすり減ります...Incomplete type 'StXY' used in nested name specifierなど。

4

1 に答える 1

2

Incomplete typeヘッダーが含まれる順序を間違えると、エラーがよく表示されます。

  • ヘッダー ファイルで適切なインクルード ガードを使用しましたか?
  • 循環インクルードがあると、前方宣言が台無しになることがあります。
  • ヘッダーをコピーして同様のヘッダー (egah と bh) を作成し、インクルード ガードを変更するのを忘れてしまうことがあります。これを追跡するのは非常に困難です。

次のことを試してください: インクルードするだけの空の .cpp を作成し、the_machine.hそれをプリコンパイルするだけです。前処理された翻訳単位を含むファイル (つまり、コンパイラが参照するすべてのコードを含む 1 つのファイル) を書き込むさまざまなコンパイラ用のコマンド ライン フラグがあります。そのファイルをチェックして、すべてがあなたが思っている順序になっているかどうかを確認してください。ほとんどのプリプロセッサは#line制御コマンドを生成し、コンパイラ (およびユーザー) に、どのヘッダー/ソースのどの行を見ているかを伝えます。

編集:

#includemachine.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には名前を付けません。それらは、単独でインクルードして使用できる単一のヘッダーではないためです。

于 2013-01-18T09:20:08.810 に答える