第56章 クロスキャスト

 今回は、第2部第42章で名前だけ話した「クロスキャスト」について話したいと思います。一体クロスキャストとは何なのでしょうか...。


 それでは、今回の要点です。


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


 継承の関わるキャストは大まかに分けて3つあります。そのうちの2つについては今までに話してきました。アップキャストとダウンキャストですね。もう1つのキャストについて話す前に、アップキャストとダウンキャストについてもう一度話したいと思います。

 先ず、アップキャストは派生クラスのポインタ(参照)から基底クラスのポインタ(参照)へのキャストでした。例えば CFile の継承関係で考えると、

CBinaryFile* pBin;
CFile* pFile = (CFile*)pBin;

これがアップキャストになります。なぜアップキャストと呼ぶかは、下の継承木を見れば一目瞭然です。

CFile
CBinaryFile CTextFile

 継承木とは継承関係を木構造で表示したものです。基底クラスを上に、派生クラスを下に書きます。ということで、アップキャストは下の方にあるクラスから上の方にあるクラスへのキャストになり、アップ(上への)キャストと呼ぶわけです。

 同じく、ダウンキャストは継承木の上の方にあるクラスから下の方にあるクラスへのキャストで、ダウン(下への)キャストと呼ぶわけです。

CFile
CBinaryFile CTextFile

 さて、これ以外にももう1つだけキャストの方法が考えられます。上の継承木を見て

CFile
CBinaryFile CTextFile

というキャストを考えた人はいませんか? しかし、これは非常に危険なキャストであって、こんなことをしてはいけません。CBinaryFile になくて CTextFile にあるメンバを使うときに危険なことになります。

 ただ、考え方自体は近いのです。アップダウン(上下)にではなく、左右のキャストがまだある可能性があるということですね。上のがダメであれば、もう可能性は1つしか残っていません。こんな感じですね。

CNinja CMaster
CJohnin

 これがもう1つのキャスト「クロスキャスト」です。

 「なんだ、これも危険なんじゃないか?」と思った人もいるでしょう。確かに、次のように CNinja のオブジェクトを使ってキャストすると危険です

CNinja   ninja;
CNinja*  pNinja = &ninja;
CMaster* pMaster = (CMaster*)pNinja;  // 危険!

 しかし、CNinja* に CJohnin のオブジェクトへのアドレスが入っている場合は問題ありません

CJohnin  johnin;
CNinja*  pNinja = &johnin;
CMaster* pMaster = (CMaster*)pNinja;  // OK

 CJohnin* は CNinja* にも CMaster* にもアップキャストできるわけですから、CJohnin* を CNinja* にキャストしたものであれば、CMaster* へキャストしても問題ないことが分かるでしょう。これがクロスキャストなのです。


 簡単にいうと、クロスキャストはダウンキャストしてアップキャストすることです。ダウンキャストを伴う以上危険性はありますが、これはダウンキャストと同じ方法で回避することが出来ます。第2部第42章に話した dynamic_cast ですね。ランタイムタイプ情報(RTTI)を有効にするのも忘れてはいけません。

 この dynamic_cast を使えば、ポインタで危険なキャストを行ったときは NULL が返ってきます第50章でちょっと話しましたが、参照でのキャストで失敗したときは std::bad_cast 例外が投げられます。

 例を挙げると、こんな感じですね...。

CNinja   ninja;
CJohnin  johnin;
CNinja*  pNinja;
CMaster* pMaster;

pNinja = &ninja;
pMaster = dynamic_cast<CMaster*>(pNinja);  // pMaster は NULL になります

pNinja = &johnin;
pMaster = dynamic_cast<CMaster*>(pNinja);  // pMaster には johnin のアドレスが入ります

 これで、安心してクロスキャストができるわけですね。


 では、今回の要点です。


 今回で多重継承に関する話題は終わりです。次回からはまた細々とマニアックな話題を続けていこうと思います。それでは。


第55章 融合3 | 第57章 メンバ関数ポインタ天国

Last update was done on 2001.6.5

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