第53章 融合

 間接的に同じクラスを複数継承させる場合、メンバ変数はどうなるのでしょうか? 今回はそういう話です。


 では、今回の要点です。


 では、いってみましょう。


 先ずは、前回の多重継承をもうちょっとよく考えてみます。

 では、前回の継承図をもう一度見てみましょう。

CFirstClass CFirstClass
CMaster CNinja
CJohnin

 このように、CFirstClass クラスは間接的に2つ継承されています。

 この継承関係は多少複雑ですが、

CMaster CNinja
CJohnin

に毛の生えた程度と考えればそう複雑というわけでもありません。

 CNinja は CFirstClass を継承しています。つまり、CNinja は CFirstClass を拡張したクラスです。これは CMaster も同じです。これら CNinja と CMaster は CFirstClass を継承していて、確かに両方とも CFirstClass への参照へオブジェクトを渡せますが、これらは基本的に独立したクラスです。

 ここでいう「独立した」という意味は、CJohnin で2つを継承しても、CNinja の CFirstClass と CMaster の CFirstClass は別物であるという意味です。CNinja 経由で CFirstClass のメンバを呼んでも、CMaster の CFirstClass には影響を与えません。

 これは CFirstClass にメンバ変数を持たせてやるとよく分かると思います。

CFirstClass CFirstClass
a : 0 a : 0
CMaster CNinja
CJohnin

 CNinja 経由で CFirstClass のメンバ変数 a を1に変えてみると、

CFirstClass CFirstClass
a : 0 a : 1
CMaster CNinja
CJohnin

と、こうなります。

 このように、CJohnin において2つの CFirstClass は独立して存在しています。こういうイメージでしょうか?

CFirstClass
CMaster
CFirstClass
CNinja
CJohnin

 しかし、継承の方法をいろいろ考えた結果、次のような継承を行いたい場合が出てくるかもしれません。

CFirstClass
CMaster CNinja
CJohnin

 CFirstClass が1つになっています。つまり、CNinja 経由でも CMaster 経由でも、同じ CFirstClass を扱うようになるわけです。

 これがどういうことかは、やはりメンバ変数を考えると分かりやすいと思います。

CFirstClass
a : 0
CMaster CNinja
CJohnin

 このように、CFirstClass が1つしかないので、a は1つしかありません。先ず、CMaster 経由で a の値を調べると、もちろんとなります。ここで CNinja 経由で a を変えて...

CFirstClass
a : 1
CMaster CNinja
CJohnin

もう一度CMaster 経由で a の値を調べると...

CFirstClass
a : 1
CMaster CNinja
CJohnin

今度はになっているわけです。


 では、こういった継承はどうやったらできるようになるのでしょうか? 前回までの方法ではこういった継承にはならないので、もうちょっと別の方法があることは分かると思います。

 実は、こういった継承は仮想継承という機構を使って行うことができます。仮想継承されたクラス同士は、同時に複数継承されなくなります。

 つまりは、CNinja で CFirstClass を継承するときに仮想継承にして、CMaster で CFirstClass を継承するときに仮想継承にしておけば、CJohnin で CNinja と CMaster を継承しても CFirstClass は1つになるのです。

 仮想継承するには、やはり virtual キーワードを使います。

class CNinja : virtual public CFirstClass
{
    ...
};

 これで仮想継承できます。


 一度に沢山話しても頭に入らないと思うので、今回は仮想継承の基本概念について話すだけにとどめ、実際のプログラムについては次回に話したいと思います。

 では、今回の要点です。


 仮想継承は、お馴染みの iostream.h にある iostream というクラスで使われています。ios というクラスを仮想継承して istream と ostream を作り、それらを継承して iostream を作っています。仮想継承が実際にどう使われているかの例としてあげておきます。

 では、次回まで。


第52章 多重継承事始2 | 第54章 融合2

Last update was done on 2001.5.19

この講座の著作権はロベールが保有しています