異種コンストラクタ制約を持つC ++ファクトリパターン

私は、コンストラクタに渡すためのクラス名と引数を提供する入力ファイルを与えられたオブジェクトをプログラムでインスタンス化できるC ++プログラムを実装しています。

クラスは共通の基本クラスから派生しますが、そのコンストラクタのシグネチャは異なります。

彼らは次のように宣言されています:

class Base { ... }
class Class1 : Base { Class1(int a1, int a2); }
class Class2 : Base { Class2(int a1, int a2, int a3); }
... and so on...

引数の型はintである必要はありません。実際には、組み込み型または複合型のカスタム型になります。

プログラム入力はJSON形式で次のようになります。

[
  { "Class1": ["arg11", "arg12"] },
  { "Class2": ["arg21", "arg22", "arg23"] },
  ...and so on...
]

Boost.Functional/Factory のドキュメントを読む私のアプリケーションでは、コンストラクタのシグネチャ(異種性の制約)が異なるという事実が私の問題を解決することができるようです。 Boost.Function/Factoryのアプローチは、コンストラクタのシグネチャを正規化することですが、これは私のアプリケーションでは不可能です。

Pythonのような動的言語では、これはやや単純です: klass = Class1 args = ["arg11、" arg12 "]

では、C ++の異種制約を持つファクトリパターンの実装についてはどうでしょうか?

Boostの他にも私が見逃している他の図書館はありますか?

これは、唯一の依存関係が標準ライブラリ(つまりBoostなし)になるように実装できますか?

さらに、コンストラクタ引数が複雑な型であり、そのJSON表現から特別に構築されなければならない場合、それが問題の複雑さにどのように影響しますか?

6
おそらくJSONはC ++クラスのシリアライゼーションに最適な選択肢ではありませんでした...代わりにboost.serializationを使用してみませんか?
追加された 著者 smerlin,
@SalmanHaq:AFAIKのブーストシリアル化はXMLをサポートしていますが、これらのXMLファイルはユーザーが読み取りまたは編集できるようには設計されていません。
追加された 著者 smerlin,
@サルマン:私がメリアム・ウェブスターのために見るより多くの参考資料、それはジャンクの大量の山だと思うほどです。次回は、Oxford English Dictionaryをお試しください。
追加された 著者 Puppy,
将来の参考として、均質の反対は異質である
追加された 著者 Seth Carnegie,
はい、私は知っている、あなたはほとんどすべての単語に ""または "un"を追加することができ、それはまだ言葉になります。それはちょうど奇妙に聞こえる。
追加された 著者 Seth Carnegie,
Hey Seth、 'Inhomogeneous'はMerriam-Websterの辞書によれば有効な単語でもあり、意味的には 'heterogeneous'と似ています。 Boost.Function/Factoryのドキュメント(これは私の記事のリンクを参照してください)の選択でもあるので、前者を選択しました。
追加された 著者 Salman Haq,
@DeadMG辞書の選択についてどう思いますか?元の質問とは無関係です。いずれの言葉の選択も十分であったはずです。しかし、文体上の理由から、一方が他方よりも好まれるなら、それは私にとっては大丈夫です。しかし、速やかに検索エンジンの結果などに関する議論に変わる言語辞書についてのディスカッションにしないでください。質問に固執してください。ありがとう!
追加された 著者 Salman Haq,
@スメリン良い点。しかし、このアプリケーションでは、プログラム入力はユーザー編集可能な形式のファイルでなければなりません。 JSONとYAMLはその目的のために法案によく合っているようです。私はboost.serializationファイル形式がバイナリであると推測していますか?
追加された 著者 Salman Haq,

2 答え

ファイルから読み込まれたパラメータの「配列」からオブジェクトを構築する方法を知っている各クラスのファクトリメソッドがあると考えましたか?

あれは:

// declared "static" in header file
Class1* Class1::FactoryCreate(int argc, const char** argv)
{
    if (argc != 2)
        return NULL;//error

    int a1 = atoi(argv[0]);
    int a2 = atoi(argv[1]);
    return new Class1(a1, a2, a3);
}

// declared "static" in header file
Class2* Class2::FactoryCreate(int argc, const char** argv)
{
    if (argc != 3)
        return NULL;//error
    int a1 = atoi(argv[0]);
    int a2 = atoi(argv[1]);
    int a3 = atoi(argv[2]);
    return new Class2(a1, a2, a3);
}
5
追加された
私は確かにこれに似たオプションを考えました。つまり、JSONオブジェクトを静的なファクトリ関数に渡してインスタンスを返すようにしました。問題は、私が扱っているコードベースがこの時点で100以上のクラスを持ち、成長しているということです。これは確かに可能な解決策ではありますが、現時点では理想的です。
追加された 著者 Salman Haq,

あなたが望むものを達成するためには、コードのある時点で、名前に基づいてどのクラスを構築するかを決定する巨大な switch - 記述(実際には switch else if のような非常に長いのように)文字列を切り替えることができないため、動作しません。

また、表示される表現には、コンストラクタ引数の型に関する情報は含まれていないようです。これは、同じ数の引数で複数のコンストラクタを呼び出し可能なクラスを持つ場合には問題になる可能性があります。

最終的には、 @selbies答えのようなものを使ってコード生成を使ってあなたのための建築コード。

1
追加された
ありがとう@bjorn&セルビー。私の場合、最良の答えはコード生成です。私のコードジェネレータは〜100行のPythonで、およそ有効なファクトリ関数を生成します。私。私は生成されたコードのいくつかをマッサージする必要があります。完全ではないコードジェネレータを使用していても、私はこの作業を達成するために非常に生産的でした。 Boost.Functional/Factoryを私のユースケースに拡張する価値はまだあるかもしれません。後で調べる。 :) FYI:C ++ヘッダー解析ライブラリ:私のニーズに適した CppHeaderParserライブラリ
追加された 著者 Salman Haq,