クラス階層の設計についてアドバイスが必要です。私の現在のデザインの「スケルトン」は
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関数を作成できることは理解していますが、理想的にはそれを避けたいと思います。
デザインを改善するための提案を歓迎します。前もって感謝します!