1. ホーム
  2. c++

[解決済み] ミキシンとは(概念的なもの)

2023-05-09 13:28:07

質問

Mixinの概念を理解しようとしているのですが、それが何なのかがよくわかりません。 私が考えるには、継承を使用してクラスの機能を拡張する方法です。 抽象的なサブクラスと呼ばれることもあるようです。この理由を説明できる人はいますか?

次の例(私の講義のスライドショーから)に基づいてあなたの答えを説明してくれるとありがたいのですが。

どのように解決するのですか?

ミックスインが何であるかを説明する前に、ミックスインが解決しようとしている問題を説明することが有用です。たとえば、モデル化しようとしているたくさんのアイデアやコンセプトがあるとします。それらは何らかの形で関連しているかもしれませんが、ほとんどの場合直交しています。つまり、互いに独立してそれ自体で立ち上がることができます。これを継承でモデル化し、各概念を共通のインターフェースクラスから派生させることができます。そして、そのインターフェースを実装している派生クラスで具体的なメソッドを提供するのです。

このアプローチの問題は、この設計が、それらの具体的なクラスのそれぞれを取り、それらを一緒に結合する明確な直感的な方法を提供しないことです。

ミックスインのアイデアは、それぞれが基本的な直交概念をモデル化した原始的なクラスの束を提供し、それらをくっつけて、欲しい機能だけを持つより複雑なクラスを構成することができるようにすることです。プリミティブクラスは、それ自体がビルディングブロックとして使用されることを意図しています。これは拡張性があり、後から他のプリミティブクラスをコレクションに追加しても、既存のクラスには影響を与えません。

C++に話を戻すと、これを行うためのテクニックとして、テンプレートと継承を使用します。基本的な考え方は、テンプレートパラメータを使用してこれらの構成要素を提供することによって、一緒に接続することです。そして、それらを連鎖させ、例えば typedef を介して、必要な機能を含む新しい型を形成します。

例として、やり直しの機能を追加したいとしましょう。以下のような感じです。

#include <iostream>
using namespace std;

struct Number
{
  typedef int value_type;
  int n;
  void set(int v) { n = v; }
  int get() const { return n; }
};

template <typename BASE, typename T = typename BASE::value_type>
struct Undoable : public BASE
{
  typedef T value_type;
  T before;
  void set(T v) { before = BASE::get(); BASE::set(v); }
  void undo() { BASE::set(before); }
};

template <typename BASE, typename T = typename BASE::value_type>
struct Redoable : public BASE
{
  typedef T value_type;
  T after;
  void set(T v) { after = v; BASE::set(v); }
  void redo() { BASE::set(after); }
};

typedef Redoable< Undoable<Number> > ReUndoableNumber;

int main()
{
  ReUndoableNumber mynum;
  mynum.set(42); mynum.set(84);
  cout << mynum.get() << '\n';  // 84
  mynum.undo();
  cout << mynum.get() << '\n';  // 42
  mynum.redo();
  cout << mynum.get() << '\n';  // back to 84
}

あなたのオリジナルから少し変更したことにお気づきでしょう。

  • コンパイル時に構成されたクラスの型を正確に知っているので、仮想関数はここでは本当に必要ありません。
  • 私は、デフォルトの value_type を追加しました。こうすることで、何度も <foobar, int> と打ち続ける必要はありません。
  • ピースを継承した新しいクラスを作成する代わりに、単純な typedef が使用されます。

これは、ミックスインのアイデアを説明するための簡単な例であることに注意してください。そのため、コーナーケースやおかしな使い方は考慮されていません。例えば undo を実行しても、おそらく期待通りの動作はしないでしょう。

余談ですが、あなたはまた この記事 を参考にしてください。