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
- ポインタ型を他のポインタ型に強制的に変換します。
dynamic_cast
と違いポインタの型変換が安全に行えるかは考慮されません。 - また整数型(
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
を明示的に書くことのメリットが全くないわけではありませんが。