2

線形計画法を解くためのライブラリを書きたいです。そのため、cplex や gurobi などの複数のソルバーが使用されます。私がすでに持っているのは、それらのそれぞれのインターフェースです(すべて、それらをソルバー固有のコードにラップする同じ関数が含まれています)。

ここで、cplex ソルバーを呼び出す LinearProgram("cplex") などによってインスタンス化できるクラス 'LinearProgram' が必要です。

私の最初のアイデアは、それぞれの関数を仮想宣言として含むすべてのソルバー インターフェイスの基本クラスであるスーパー クラス 'ソルバー' を使用することでした。しかし、インスタンス化できない抽象クラスを取得します。したがって、LinearProgram では、コンストラクターで指定された文字列に応じてインスタンス化される変数 Solver が必要でした。

適切な解決策は明らかだと思いますが、現時点で考えられるのは満足のいくものではありません。

ご協力いただきありがとうございます。

4

2 に答える 2

0

2つの異なるデザインパターンを組み合わせた作品です。

1 つ目はEnvelope Letterパターンで、2 つ目はStrategy パターンです。

現在使用している基本クラスを維持し、埋め込みポインターへの呼び出しを基本クラスに転送するだけの派生クラスを作成します。派生クラスは、自由に値渡しできるものになりました。

基本クラスには、基本クラスへのポインターを返す静的メンバー関数を含めることもできます。この静的メンバー関数を使用すると、文字列名を使用して検索することにより、派生クラスをインスタンス化できます。これにより、実行時にアルゴリズムを選択する便利な方法が提供されます。

しかし、どの派生クラス (どの戦略) が必要かを知っている人は、'new' を使用してクラスを作成し、それをエンベロープ クラスのインスタンス内に詰め込むことができます。

shared_ptr代わりに a を基本クラスに使用することにした場合は、必要に応じてエンベロープ クラスを廃止できます。

于 2012-11-05T20:09:31.327 に答える
0

これはあなたが説明することを示しています:

class Solver {
...abstract base
};

class SolverFactory {
public:
    Solver* NewSolverWithName(const std::string& pSolverName);
};

class LinearProgram {
public:
    LinearProgram(const std::string& pSolverName) :
      d_solver(SolverFactory::NewSolverWithName(pSolverName)) {
    }
private:
    some_auto_pointer<Solver> d_solver;
};

class cplex_Solver : public Solver {
...
    static std::string Name();
};

Solver* SolverFactory::NewSolverWithName(const std::string& pSolverName) {
    if (pSolverName == cplex_Solver::Name()) {
      return new cplex_Solver();
    }
    ...
}
于 2012-11-05T20:08:26.167 に答える