5

現実世界のシナリオをシミュレートするために使用される C++ アプリケーションを開発しています。このシミュレーションに基づいて、私たちのチームは、このような現実世界のシナリオで機能するさまざまなアルゴリズムを開発、テスト、評価します。

いくつかのシナリオを定義する可能性 (いくつかのパラメーターが異なる可能性がありますが、将来のシナリオでは新しいクラスのオブジェクトを作成する必要があるかもしれません) と、アルゴリズムのセットを維持する可能性 (これもパラメーターのセットですが、また、作成するクラスの定義)。パラメータはコンストラクタでクラスに渡されます。

すべてのシナリオとアルゴリズムの構成を管理するには、どの方法が最適なのか疑問に思っています。ある開発者が「彼の」アルゴリズムを使用してあるシナリオに取り組み、別の開発者が「彼の」異なるアルゴリズムを使用して別のシナリオに取り組むことは容易に可能です。それでも、パラメータ セットは巨大である可能性があり、「共有可能」である必要があります (シナリオ A で特定のアルゴリズムのパラメータ セットを定義した場合、コピー & ペーストなしでシナリオ B のアルゴリズムを使用できるはずです)。

私のタスクを達成するには、主に2つの方法があるようです。

  • 私の要件を処理できる構成ファイル形式を定義します。この形式は、XML ベースまたはカスタムの場合があります。C++ には C# のようなリフレクションがないため、新しいアルゴリズム クラスがプロジェクトに追加されるたびに構成ファイル パーサーを更新する必要があるようです ("MyClass" のような文字列を MyClass の新しいインスタンスに変換するため)。 )。すべてのセットアップの名前を作成し、この名前をコマンド ライン引数として渡すことができます。

    • 長所は次のとおりです。パラメータを変更して再実行するためのコンパイルは不要です。シミュレーション結果とともに構成ファイル全体を簡単に保存できます。
    • contra: 与えられたテンプレート引数でインスタンス化する必要がある多くのテンプレート クラスを使用しているため、特に大変です。ファイルを書き込むためのIDEサポートはありません(少なくとも、パラメーター/クラスが追加されるたびに更新する必要があるXSD全体を作成する必要はありません)
  • すべてを C++ コードで接続します。さまざまな作成ロジックをすべて分離するためにこれを行う方法は完全にはわかりませんが、シナリオ間でパラメーターを再利用できます。また、すべてのセットアップに(文字列)名前を付け、この名前を使用してコマンドライン引数からセットアップを選択しようと思います。

    • 長所: タイプ セーフ、IDE サポート、パーサー不要
    • 短所: 設定を結果とともに簡単に保存するにはどうすればよいですか (シリアライゼーションの可能性もありますか?)?、パラメータを変更するたびにコンパイルが必要です

ここに私の質問があります: - あなたの意見は? 重要な長所/短所を見逃していませんか? - 3 番目のオプションを見逃しましたか? - 十分な柔軟性を提供する構成ファイル アプローチを実装する簡単な方法はありますか? - セカンド アプローチですべてのファクトリ コードをどのように整理しますか? このようなものに適した C++ の例はありますか?

どうもありがとう!

4

3 に答える 3

2

テンプレートやリフレクションなしでこれを行う方法があります。

まず、構成ファイルから作成するすべてのクラスに共通の基本クラスがあることを確認します。this を呼び出して、とMyBaseClass仮定してMyClass1、すべてがそれを継承します。MyClass2MyClass3

次に、 、MyClass1MyClass2およびのそれぞれに対してファクトリ関数を実装しますMyClass3。これらすべてのファクトリ関数のシグネチャは同一でなければなりません。ファクトリ関数の例は次のとおりです。

MyBaseClass * create_MyClass1(Configuration & cfg)
{
  // Retrieve config variables and pass as parameters
  // to the constructor
  int age = cfg->lookupInt("age");
  std::string address = cfg->lookupString("address");
  return new MyClass1(age, address);
}

3 番目に、すべてのファクトリ関数をマップに登録します。

typedef MyBaseClass* (*FactoryFunc)(Configuration *); std::map<std::string, FactoryFunc> nameToFactoryFunc; nameToFactoryFunc["MyClass1"] = &create_MyClass1; nameToFactoryFunc["MyClass2"] = &create_MyClass2; nameToFactoryFunc["MyClass3"] = &create_MyClass3;

最後に、構成ファイルを解析し、それを繰り返し処理して、クラスの名前を指定するすべてのエントリを見つけます。そのようなエントリが見つかったら、nameToFactoryFuncテーブルでそのファクトリ関数を検索し、関数を呼び出して対応するオブジェクトを作成します。

于 2011-03-28T19:04:59.323 に答える
0

XML を使用しない場合、boost::spirit によって、直面している問題の少なくとも一部が回避される可能性があります。これは、構成データをクラス インスタンスに直接解析する方法の簡単な例です。

于 2010-09-14T13:32:37.393 に答える
-1

コードで使用されると思われるファクトリをサポートする素敵なテンプレートを備えたこのWebサイトを見つけました。

于 2010-09-15T07:48:43.123 に答える