1

クラス階層の設計についてアドバイスが必要です。私の現在のデザインの「スケルトン」は

template <class X>
class BASE {
  public:
    virtual void f() {
        x_.f2(m_);
    }

    void g() {
        /* do stuff here*/
        x_.g();
    }

    /* more member functions here*/

  protected:
    X x_;
    int m_;
};

template <class X>
class DERIVED : BASE<X> {
    public:
      virtual f() override {
         x_.f1();
      }

     protected:
     using BASE<X>::x_;
     using BASE<X>::m_;
};

そして最後に、このようなクラスがさらに2つあります

struct X1 {
  void f1();
  void g();
};

struct X2 : X1 {
void f2(int m);
};

のインスタンスを作成できるようにしたいと思いますDERIVED<X1>。そのために、コンパイラは最初に のインスタンスを作成しますBASE<X1>。この場合、X1 にはメンバー関数 f2 がないと文句を言います (ただし、呼び出し関数 f() は仮想であるため、実際には決して呼び出されません)。

テンプレート化されたクラスを持つためには、テンプレート引数が同じインターフェースを持つ必要があるため、これは悪い設計であることを理解しています。私の場合、X1 と X2 には共通のインターフェースがありますが、X2 にはより多くの機能があり、上記の問題が発生します。X1で何もしないf2関数を作成できることは理解していますが、理想的にはそれを避けたいと思います。

デザインを改善するための提案を歓迎します。前もって感謝します!

4

2 に答える 2

0

具象クラスからの派生は避けてください。インターフェイス/ABC を一番上に持ち上げ、すべての具象クラスを残します。これは、さまざまな種類の設計上の問題に対する一般的なアドバイスです。

あなたの特定のケースでは、これの代わりに:

             BASE    // concrete
              | 
           DERIVED

これを使って:

             BASE   // fully abstract
            /   \
BASIC_DERIVED    ADVANCED_DERIVED

fは純粋な仮想環境でBASE、すべて順調です。

于 2013-07-30T11:22:35.660 に答える