web-dev-qa-db-ja.com

C ++ミックスインスタイルとは

このキーワードを見つけましたC++ Mixin-Style、これが何か知っている人はいますか?

この投稿 では、デザインパターンとして回答されています。 このドキュメント で説明されているのと同じデザインパターンですか?

35
Bitmap

Mixins はLISPのコンセプトです。 ドブス博士 からの良い説明:

ミックスインは、他のクラスまたはミックスインで構成することを意図しているという意味で、クラスのフラグメントです。
[...]
通常のスタンドアロンクラス(Personなど)とミックスインの違いは、ミックスインが小さな機能スライス(たとえば、印刷または表示)をモデル化することであり、スタンドアロンでの使用を意図していません。むしろ、この機能を必要とする他のクラス(たとえば、Person)で構成されると想定されています。

したがって、ミックスインのポイントは、likeのような多重継承を許可することです。通常、多重継承に伴うすべてのBad Things™は不要です。

ただし、C++はネイティブでミックスインをサポートしていないため、これは少し混乱する場合があります。 C++でミックスインを「実行」するには、多重継承を使用する必要があります。これが実際に意味することは、引き続き複数継承を使用することですが、使用を許可する対象を人工的に制限することです。

実際のミックスイン実装については、上記の記事を参照してください。

私がこれを正しく覚えている場合、C++でミックスインを作成するには少なくとも2つの方法があります。これは、私が見た非常に古い(1995)チュートリアルに由来しています(ただし、ほとんど完全にインターネットから消えています)。

最初、

class MixinBase {
public :
    void f() {};
};

template<class T>
class Mixin : public T {
public:
    void f() {
        T::f();
        T::f();
    }
};

template<class T>
class Mixin2 : public T {
public :
    void g() {
        T::f();
        T::f();
    }
};

int main() {
    Mixin2<Mixin<MixinBase>> mix;
    mix.g();
}

または、仮想継承と兄弟呼び出しを使用する別の方法:

class Base {
public :
    virtual void f() = 0;
};

class D1 : public virtual Base {
public :
    void g() {
        f();
    }
};

class D2 : public virtual Base {
public :
    void f() {
    }
};

class D : public D1, public D2 {
};

int main() {
    D d;
    d.g();
}

MixinとMixin2は独立したクラスであるため、これらの両方のバージョンはミックスインを実装しますが、通信は可能です。そして、この種のモジュールからソフトウェアを作成し、後でそれらのモジュールを1つの大きなソフトウェアにバインドすることができます。仮想継承のD1とD2の間でも同じことが起こります。 mixinの設計では、異なるモジュールが同じc ++オブジェクト内にあることに注意してください。 (ああ、CRTPは別のテクニックです)

15
tp1

Mixinは、別のコードに直接含めることで再利用することを目的としたクラス(またはコードの他のグループ)です。サブタイプのポリモーフィズムのない継承と考えてください。 CRTPは、C++でMixinを概算する方法です。

8
Mankarse

C++のミックスインは 奇妙な繰り返しテンプレートパターン (CRTP)を使用して表現されます。 この投稿 は、他の再利用手法に比べて提供されるものの優れた内訳です...コンパイル時のポリモーフィズム。

5
Jesse Pepper

通常、ミックスインは小さなクラス(多くの場合、テンプレートまたはcrtpベース)と呼ばれ、いくつかの機能を「ミックスイン」するためにそこから派生します。通常、多重継承を介して、ポリシーベースの設計で実行されます(Alexandrescuによる「Modern C++ Design」も参照)。

4
PlasmaHH