3

アイテムのコレクション「ItemA」を含むクラス「BaseA」があるとします。ここで、「BaseA」を拡張して機能を追加したいので、「BaseA」から「DerivedA」を派生させます。「DerivedA」の特徴の 1 つは、「ItemA」アイテムではなく、より洗練された「DerivedITemA」アイテムを処理する必要があることです。

class BaseA {
protected:
    vector<ItemA> x;
    void m1(int i) { x.m1(i); }
};

class ItemA {
protected:
    void m1(int i) { ... }
};

class DerivedItemA : public ItemA {
    void m2(int i) { ... }
};

今、私はこの種の何かを処理したいと思います:

class DerivedA : public BaseA {
    vector<DerivedItemA> x;
    void m2(int i) { x[i].m2(); }
};

つまり、Derived クラスで派生アイテムを処理します。上記の x の定義は、BaseA のものと衝突するため、正しくありません。しかし、アイデアは、x を処理する BaseA のすべてのメソッドを、ItemA 要素を処理し、DerivedItemA 型のデータの余分な複雑さを処理するための DerivedA の拡張メソッドを持っている限り、再利用できるようにしたいということです。

なにか提案を?私の現在の考えは、x の新しいデータ型 (たとえば、VectorOfItemA) を定義し、そこから VectorOfDerivedItemA を派生させることです。よりシンプルでより良い解決策があるのだろうか。

ありがとう

4

3 に答える 3

0

すべてのクラスを所有していますか? その場合は、代わりにテンプレート基本クラスにリファクタリングできます。

template <typename ITEM>
class BaseT {
protected:
    vector<ITEM> x;
    void m1(int i) { x[i].m1(); }
};

typedef BaseT<ItemA> BaseA;

class DerivedA: public BaseT<DerivedItemA> {
    void m2(int i) { x[i].m2(); }
};

BaseAも受け入れるコードを再利用する場合DerivedAは、それらをテンプレート関数/クラスにも変更する必要がある場合があります。

それ以外の場合は、ベクター用にある種の「ポリモーフィック」ベース オブジェクトが必要になります。そのようなアプローチの 1 つについては、異種の std::list からのデータの取得(または私のフォローアップの質問: unique_ptr メンバー、プライベート コピー コンストラクターと移動コンストラクター) を参照してください。


ポリモーフィック アイテムの代わりに、ベースのインターフェイスを定義できます。

class BaseI {
protected:
    virtual void m1(int) = 0;
    //... other interfaces
public:
    virtual ~BaseI () {}
    //... other public interfaces
};

template <typename ITEM>
class BaseT : public BaseI {
protected:
    vector<ITEM> x;
    void m1(int i) { x[i].m1(); }
    //...implement the other interfaces
};

//...

現在、 を受け取るコードはBaseA、代わりに を受け取るようにリファクタリングする必要がありますBaseI。その新しいコードは a も受け入れることができDerivedAます。

于 2013-04-05T18:51:22.530 に答える