動的継承とは

C++で提供している機構では、静的な継承しか許されていない。 しかし、動的継承に近いことは可能である。
この方法は、「オブジェクト指向における再利用のためのデザインパターン」(SOFTBANK) の本に出てくるDecoratorパターンを読んで気づいたものである。

この方法の特徴をあげよう。

メリット

デメリット 見ての通り、メリットよりデメリットの方が多く、殆ど使う機会はないかもしれない。 実際、有用となるのは、「掛算の数のクラスを足算の数に減らせる場合」ぐらいであろう。 しかし、プログラマとして興味をそそられる手法ではある。

さて、例を見てみよう。
次のような部品があるものとする。

さらに、次のような種類があるものとする。 (これを属性にしてしまったら、話は進まないので、クラスにしなければいけないとしよう。) つまり、「通常ウィンドウ」、「枠付ウィンドウ」、「影付ウィンドウ」、 「通常ボタン」、「枠付ボタン」、「影付ボタン」、 「通常メニュー」、「枠付メニュー」、「影付メニュー」の9つのクラス(n×m)が 必要ということになる。

これを、「ウィンドウ」、「ボタン」、「メニュー」、「通常」、「枠付」、「影付」の 6つのクラス(n+m)でやろうというのが、動的継承である。 (まあ、常識で考えると「通常」はいらないかもしれないが。)

具体的にちょっと書いてみよう。

	struct Widget {
		virtual void Draw();
	};

	struct Window : Widget {
		void Draw(){ ... /* ウィンドウを描く */ }
	};

	struct Border : Widget {
		Widget*	m_p;
		Border(Widget* p) : m_p(p) {}
		void Draw(){ p->Draw(); ... /* 枠も描く */ }
	};

		Window	w;
		Widget*	p = new Border(&w);	// これが動的継承
		p->Draw();
		Widget*	p2 = new Shadow(p);
		p2->Draw();			// 枠も影も描く
(上のプログラムでは、雰囲気だけ分かるように手を抜いてある。)
これを見ても分かるように、何段にも重ねて継承を行うこともできる。 詳細については、先の本を参照して欲しい。

個人的には、何らかのインタープリタを実装するとき役に立つかもしれないと思っている。

戻る