C++のキャストについてあまりよく知らなかったので調べた。
static_castとreinterpret_cast
まずstatic_cast
とreinterpret_cast
はどちらも型を強制的に変換するものという認識で、違いがよく分かってなかった。
reinterpret_cast
は無条件にポインタを変換するのに対し、
static_cast
は変換元と先のクラスが親子関係でなければコンパイルエラーが発生する、という違いがある:
Foo* foo; |
ということでどちらかというと static_cast
の方が用途が少し制限されている、という違いがある。
言うなれば reinterpret_cast
がCのキャストと同じもの。
void*
からの変換にはどちらも使える- コンパイル時に判定するだけなので、実行時には判定や変換処理というものはない
- どちらも変換後の内容が正しいかどうかは保証されない
多重継承している場合
Base1
と Base2
を継承した Derived
クラスがあったとする。
Derived
から Base2
にアップキャストした場合、第1の親クラスじゃないのでポインタがずれる。
その状態から Derived*
への static_cast
を使用すると、オフセットを考慮してダウンキャストされ、元のポインタが復元できる。
reinterpret_cast
では考慮されないので復元はできない(オフセットがずれたまま)。
コンパイルでワーニングが出る:
reinterpret_cast<Derived*>(b2); |
dynamic_cast
dynamic_cast
は通常ダウンキャスト(親クラスから子クラスへの変換)に使用する。
実行時に実際に意図したクラス(またはそれを継承したクラス)かどうかを判定して
そうであれば変換し、違ったら nullptr
を返す。
実行時型情報(RTTI)を用いるので、仮想関数を持っている必要がある。
多重継承している場合
dynamic_cast
で Base2*
から Derived*
が復元できる。
const_cast
const_cast
はコンパイル時に const
ポインタをconstなしポインタとして解釈するよう指示するだけなので、特に不明点はない。