キャストの詳しい説明¶
C++ の4種類のキャスト演算子には以下のような違いがあります。
キャスト演算子 | CV 修飾子の除去 | CV 修飾子以外の型情報の変更 | ビット表現の変換 |
---|---|---|---|
static_cast | |||
dynamic_cast | |||
const_cast | |||
reinterpret_cast |
CV 修飾子の追加はどのキャストでも行うことができます。
CV 修飾子¶
const
修飾子と volatile
修飾子 をまとめて CV 修飾子と呼びます。
volatile
修飾子は
cv (const および volatile) 型修飾子 - cppreference.com
を参照してください。
static_cast と dynamic_cast¶
static_cast
と dynamic_cast
は値の変換方法を決定するタイミングが違います。
static_cast
はコンパイル時に決定dynamic_cast
は実行時に決定
この違いによって安全にダウンキャストができるかなどの差があります。 詳細は ダウンキャスト を参照してください。
ビット表現の変換¶
static_cast
や dynamic_cast
では型の変換と同時にビット表現を変換しますが、
reinterpret_cast
ではビット表現を変更せずに型だけを変更します。
整数型と浮動小数点数型などビット表現が異なる型の変換を行うと、 値の変換の有無によって挙動の差異が生じます。
double x = 2;
int64_t s = static_cast<const int64_t&>(x);
int64_t r = reinterpret_cast<const int64_t&>(x);
std::cout << s << std::endl; // 2
std::cout << r << std::endl; // 4611686018427387904 (IEEE 754 の場合)
一般に派生クラスから基底クラスへアップキャストする場合にもビット表現の変換は必要です。 たとえば 多重継承 をしている場合に、 オフセットが 0 ではない基底クラスへアップキャストすると正しい値を参照することができません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|
C++ のキャストではできないこと¶
C++ のキャストではアクセス指定子を無視した変換などは行えませんが、 C 言語形式のキャストなら変換することができます。
アクセス指定子を無視した変換が必要となるのはクラス設計に問題がある場合なので、 C 言語形式のキャストを用いるのではなく、 アクセス指定子を修正して C++ のキャストを使用しましょう。
詳細は 明示的な型変換 - cppreference.com を参照してください。