恥ずかしながら、つい最近まで、C++ で導入されたいくつかのキャスト操作の 違いを、明確に認識していなかった。「そんなヤツの書くことは全く信用ならん」 と仰る? 当然の反応だとも思うが、そういう方は、まず、こちらの 「C++の新しいキャスト」 というページをご覧いただいて、予備知識を得ておいてほしい。 ちなみにここは、「C++ キャスト」をキーワードにして Google で検索したときにトップにランクされたページである (2001年3月1日現在)。
で、はっきり言って、キャストについては、「C++の新しいキャスト」のページで あらかた説明が済んでしまっている。ここに述べることは蛇足のようなものだが、 キャストの研究中に作成したソースリストを最後に載せておくので、理解の一助と していただければ幸いである。
const性の除去のみを目的としたキャストである。逆に、const 性の除去は、 const_cast 以外のキャストでは不可能である (まあ、Cスタイルのキャストを 使えば可能だが…)。これ以上の説明は不要だろう。
「C++の新しいキャスト」で述べられているように、変換元の型から変換先の型へ、 あるいは、変換先の型から変換元の型への暗黙の型変換が存在する場合にのみ、 キャストが成功する。
とくにポインタの型変換においては、
void * と任意のポインタの間はキャスト可能主に、派生関係にあるクラスのポインタ間で、安全性を保証したキャストを行う ために用いられる。ポインタが実際に指しているオブジェクトの型を、実行時に 判定するので、「dynamic」と名づけられているわけである。
ダウンキャストやクロスキャストが可能であるためには、ポインタは、 ポリモーフィックでなければならない。つまり、基底クラスは、少なくとも1つの 仮想関数を持たなければならない。というのも、オブジェクトの型に関する情報は 仮想関数テーブル (vtbl) に埋め込まれるからである。
単に、指定された型に読み替えるだけである。ポインタの場合、アドレスは 変わらない。これは、多重継承を使っている場合に問題をひきおこす。多重継承に おいては、アップキャスト、ダウンキャスト、クロスキャストに際して、各基底 クラスに相当するオブジェクトの配置に従って、ポインタの値を変える必要が あるからである。
一方、まったく無関係なクラス間で、ポインタの読み替えを行うこともできる。 これが可能なのは、reinterpret_cast と、Cスタイルのキャストだけで ある。
従来の Cスタイルのキャストは、const_cast と static_cast と reinterpret_cast をミックスしたものである。つまり、
以下に、ポインタ間の変換を例にとって、各キャスト演算子がどのように働くかを 調べるために作成したソースリストを載せる。調査が目的なので、new したオブジェクトを 律義に delete したりはしていない。そういうところではツッコミを入れないように。 使用したコンパイラは、g++ (version 2.95.2) である。
キャストとの闘いの記録初出: 2001年3月1日