2

私は次の問題を抱えています(簡略版):

Interface X;
class Y : public X { ... }
class Z : public X { ... }

class A
{
    map<int, X> m;
    init() { X bla = new Y or Z; map.insert(...) }
}

Aの作成時にYまたはZを指定したいので、指定したタイプに基づいて異なる機能を取得します。現在、Aを「テンプレート化」することはできますが、1つのメソッドでのみ使用する必要がある場合でも、Aに対して定義するすべての関数でテンプレートを指定する必要があります。また、g ++ 4.2.4を使用しています。これは、関数の実装をヘッダーファイルから分離できないことを意味します。

4

3 に答える 3

3

テンプレートのように聞こえるのは確かにやり過ぎであり、何らかの形の依存性注入がより適切です。Xたとえば、 inの特定のインスタンスをに渡すことができますA::init

init(X &bla) { map.insert(...); }

または、ファクトリ関数を渡します。

init(X (*factory)()) { X bla = factory(); map.insert(...); }

または、これらのいずれかを実行しますが、インスタンスまたはファクトリ関数をのコンストラクタに渡しますA

于 2012-12-03T20:25:23.127 に答える
2

の使用から明らかなようにnew、それが実際にはmap<int, X*> mandである場合は、テンプレートパラメータに基づいてまたはを作成するX* bla=...だけで「テンプレート化」できます。init()YZ

別の方法として、;をX返す派生オブジェクトのファクトリメソッドを作成することもできます。または、の呼び出し元に、適切な派生型を返すファクトリ関数を指定してもらいます。Y *Z *enuminitX

于 2012-12-03T20:24:59.330 に答える
2

...1つの方法でのみ使用する必要があるにもかかわらず...

Aこの場合に通常行われることは、テンプレート化されていない共通機能を基本クラスに移動し、基本機能を継承するテンプレート化を定義することです。すなわち:

class A_base {
    // common things go here, they can be implemented in a .cpp file.
};

// This is the part that depends on T
template<class T>
class A : public A_base
{
    map<int, T> m;
    void init() { T *bla = new T; map.insert(...) }
};

これは、コードの膨張を減らすための一般的な手法です。A_baseのメソッドを呼び出す必要がある場合はA、それを作成できますvirtual

于 2012-12-03T20:33:57.373 に答える