階層順に積み重ねることができる長方形があるシステムに取り組んでいます。したがって、ベースは次のようなものです。
Rect parent;
Rect child;
parent.addChild(&child);
...
Rect* someChild = parent.getChildAt(1);
ここまでは簡単に実装できます。しかし、これらの長方形はさまざまな機能を実装できるはずです。これは、シリアライザー、スタイラー、ドロワーなどである可能性があります...
これで、多重継承が一種の「ダメ」であることがわかりましたが、この場合、次のような構文が望ましいと思います。
class StackableStyleableRect: publicRect, public Stackable, Styleable{}
class StackableStyleableDrawableRect: public Rect, public Stackable, Styleable, Drawable{}
私は、正しく理解すれば上記を可能にする奇妙な繰り返しのテンプレートパターン (crtp) に出くわしました。このようなもの:
class Rect{
public:
float width;
float height;
}
template <class RectType>
class Stackable{
public:
void addChild(RectType* c){
children.push_back(c);
}
std::vector<RectType*> children;
}
template <class RectType>
class Drawable{
public:
virtual void draw(){
RectType* r static_cast<RectType>(this);
drawRect(r->width, r->height);
}
}
template <class RectType>
class Styleable{
public:
int r, g, b;
}
class CustomRect: public Rect, public Stackable<CustomRect>, public Drawable<CustomRect>{
}
class CustomRectWithStyle: public Rect, public Stackable<CustomRect>, public Drawable<CustomRect>, public Styleable<CustomRect>{
public:
}
この理由は、さまざまな種類の Rect 型でコードを再利用したいからです。あるプロジェクトでは、スタイルを設定する必要はありませんが、別のケースでは、提供されているすべての機能が必要になります。このように必要な機能を選択することで、物事をすっきりさせ、機能を分離することもできます。
これでいくつかの基本的なテストを行い、期待どおりに動作しますが、時間の経過とともに構文が過度に複雑になる可能性があると感じています.
また、ある時点で、コンポーネントを相互に依存させたり、コンポーネントが存在する場合に異なる動作をさせたりすると便利です。(たとえば、Drawable の draw 関数は、Styleable が存在する場合は自動的にその色を使用できます)
今、遅かれ早かれトラブルに遭遇する運命にあるのでしょうか、それともうまくいくでしょうか? よりフィットする別のパターンはありますか?それとも、「適切な」C ++でこのようなことを行うことは単に不可能ですか?