読者です 読者をやめる 読者になる 読者になる

ポリシークラスってなんぞや?〜その3〜

1章 1.3 多重継承で解決できるのか?

多重継承によって、選択の組み合わせの爆発的な増加に対応するという手が考えられます。
例えば、Temporaryクラスと、Secretaryクラスを継承してTemporarySecretaryを作ったり、BaseSmartPtrと、RefCountedと、MultiThreadedを継承して、MultiThreadedRefCountSmartPtrを作ったり。

しかし、著者は以下の3つの理由により、これでも十分ではないと述べています。

  • メカニズム
  • 型情報
  • 状態の操作

の3つです。
1つづつ見ていきます。

メカニズム

継承するコンポーネントを統制の取れた手段で組み立てるための定型的手法が存在していません。
(中略)
つまり言語レベルでは、基本となるクラス群に対して単純な重ね合わせを適用し、
各メンバにアクセスできるようにするための単純な規則の集合しか導入されないのです。
...

正直よくわからんかったです。

多重継承という仕組みだけだと、なんでもかんでも組み合わせることができてしまう。
極端な話、MultiThreadedと、SingleThreadedを同時に継承したり、PlayerとEnemyとCameraを同時に継承したり、できてしまう。
なんで、「これと、これと、これを組み合わせるといいんだよー。」っていうのをユーザーに知らせる仕組みが欲しいってことかな?

型情報

基底クラスには作業を行うための十分な型情報を含めることができません。

これは、なんとなくわかる。

深いコピーを可能にするDeepCopyクラスがあったとして、copyという関数だとか、operator= だとかを定義しようとする。 けど、実際にDeepCopyクラスが、どんなクラスに継承されるかは、継承されるまでわからない。このような状況を、「十分な型情報を含めることができません。」と言っているのかなと。

状態の操作

基底クラスを用いて実装される様々な動作は、同じ状態を操作しなければなりません。
これは状態が保持されている基底クラスを継承するには仮想継承を用いなければならないことを意味しています。
これにより、ユーザー・クラスはライブラリ・クラスを継承するものの、
その逆は許されないということが前提となるため、設計は複雑化し、柔軟性がなくなるのです。

うーん。よくわからじ。

つまり、状態をaとすると、

a  a  a
|  |  |
B  C  D
 \|/
   E

↑な感じで実装することが強いられてしまうということなんだと思うんだけど。

その逆は許されないということが前提となるため、設計は複雑化し、柔軟性がなくなるのです。

のあたりが具体的にイメージできない。
無念。

今日は、ここまで。