C++と 4 つのキャスト演算

static_cast

ある型からある型への暗黙の変換が存在する時に(たとえばintからdoubleなど)、そこで暗黙の変換が行われることを明示する場合に行います。 多くの場合はstatic_castは省略することが可能です。

double d = 3.14;
int i = static_cast<int>(d);

dynamic_cast

親クラスの型のポインタを子クラスのポインタにキャストするときに利用します。 この際、その親クラスの型のポインタが指すオブジェクトの実体のクラスがキャスト先のクラスであることを確認されます。 ポインタが指す実体がキャスト先のクラスまたはその子孫クラスである場合はポインタはそのまま使われますが、 そうでなくキャスト先のクラスとして使用できない場合にはNULL(nullptr)に置き換えられます。

Child0 child0;
Parent* parent = &child0;
// Child1* child1 = parent; <-- compile error.
Child1* child1 = dynamic_cast<Child1*>(parent);
Child0* child0_2 = dynamic_cast<Child0*>(parent);
// child1 is nullptr. child0_2 == child0.
cout << "child1: " << child1 << ", child0_2: " << child0_2 << endl;
cout << "child0_2->name(): " << child0_2->name() << endl;

dynamic_castを行うためには、型情報がポインタから得られる必要があります。つまりクラスはpolymorphicである必要があります。 つまり親クラスは最低でも 1 つのvirtualな関数が親クラスに定義されていてvtableが存在しなくてはなりません。

reinterpret_cast

  1. ポインタ型を他のポインタ型に強制的に変換します。dynamic_castと違いポインタの型変換が安全に行えるかは考慮されません。
  2. また整数型(int, long, long longなど)を任意の型のポインタに変換するのにも利用できます。
int j;
char* c = reinterpret_cast<char*>(&j);
c[0] = 1;
c[1] = 1;
// 257 in little-endian.
cout << "j: " << j << endl;
long addrint = reinterpret_cast<long>(c);
cout << "addrint: " << addrint << endl;
// Note: reinterpret_cast<int>(c); causes a compile error.

const_cast

ポインタ型、参照型にconstをつけたり外したりするのに使えます。驚くべきことに C++ではconst_castを使って型についている const を外すことが許されています。 とはいえ当然constはこの変数は今後変更されないということを表しているのですから、それを解除してしまうのは問題があります。 互換性などの問題でどうしても使わざるを得ない場合以外では使うべきではないでしょう。 逆にconstへのキャストで一番多いのはconst &な関数の引数として変数を渡す場合だと思いますが、この場合にわざわざconst_castをつけることはあまりしないと思うので、結局const_castを使うことはあまりないです。

const_cast<>を呼び出し側に明示することで引数がconstだと一見して明らかになるので、const_castを明示的に書くことのメリットが全くないわけではありませんが。

最終更新: 2016/12/18