5

私は基本クラスへのポインタの束を保持するコンテナと、何らかの入力を受け取り、基本クラスのサブクラスであるクラスを返す関数を持っています。それが返すサブクラスは入力に依存します。これを設計する任意のより良い方法がある場合、私は思っていたコンストラクタの巨大なスイッチステートメント

class Base { ... } 

class A : public Base { ... } 
class B : public Base { ... } 
... 
class Z : public Base { ... } 

Base* depends(int input) { 
    switch (input) { 
    case 1: 
     return new A(...); 
    case 2: 
     return new B(...); 
    ... 
    case 26: 
     return new Z(...); 
    default: 
     ... 
    } 
} 

は今のところ、私はこのような巨大なswitch文を持っています。私は多くの "デザインパターン"(私は彼らが呼んでいると思う)を知らないので、これを設計する(明らかな)よりよい方法があるかどうかわかりません。

+1

あなたのキーをクラスやクラス名(あるいはあなたのキーがintの場合は配列)にマッピングするディクショナリを持つことは素晴らしいことです。しかしこれは可能ですか?同様の質問を参照してください:http://stackoverflow.com/questions/582331/c-is-there-a-way-to-instantiate-objects-from-a-string-holding-their-class-name –

+0

@レイ感謝リンクについては、その質問は私のものと非常に似ており、かなり多くの回答があります。 –

答えて

6

お探しのものはです。

ここで重要なことは、派生クラスの実装に関する知識をBaseクラスが持つ必要性を取り除くことです。 BaseクラスがDerivedクラスに関する知識を持っているのは悪い設計です。

ファクトリメソッドパターンは、作成がベースクラスの外部で行われるため、上記の問題を解決します。

1

入力パラメータに基づいてさまざまなサブクラスを作成する場合は、抽象ファクトリパターンを考慮する必要があります。

1

別の方法は、対応するコンストラクタを呼び出す関数へのポインタを配置する配列を作成することです。また、depends()では、与えられた入力だけで必要な関数を呼び出すだけです。しかし、この方法では26の関数が必要です。

1

整数パラメータ "input"はどこかから来ます。そのintを作成したコードに実際のオブジェクトを作成させることができます。あなたがディスクなどからintを読み込んでいる場合、それはうまくいかないでしょう。

異なるサブクラスがそれらを作成するオブジェクトに登録される状況を設定することを検討することがあります。その場合、ファクトリオブジェクトはコンパイル時にサブクラスについて知る必要はありません。起動時に、コンストラクタが各サブクラスごとに登録を行うグローバル変数を使用してこれを行うことができます。 switch文はより簡単で高速ですが、サブクラスを変更するときにスイッチを最新の状態に保つ必要があります。それはトレードオフであり、私はあなたのソリューションがより精巧なものに必ずしも劣っているとは思わない。

+0

残念ながら、それはまさにこのプログラムが行うことです - ファイルからデータを読み込みます。このプログラムには、それが得ることができる効率のあらゆるビットが必要なので、私は 'switch'をつけることが良い方法になると思います。ありがとう。 –

+0

@Seth Carnegieあなたがやりたいことは、classIdのような静的なconstフィールドをサブクラスで定義することです。オブジェクトを作成するコードとディスクにIDを書き出すコードの両方が、同じフィールドを参照することができます。 –

+0

ええ、そうです。私はむしろそのRTTIをしたいと思います。 –