まず、キャストとは、ある型の値を別の型の値に変換する明示的な要求であることに注意してください。また、キャストは常に新しいオブジェクトを生成します。これは、キャスト オペレーターによって一時的に返されるものです。ただし、参照型にキャストしても、新しいオブジェクトは作成されません。値によって参照されるオブジェクトは、別の型の参照として再解釈されます。
今あなたの質問に。変換には主に 2 つのタイプがあることに注意してください。
- プロモーション: このタイプは、おそらくより狭いタイプからより広いタイプへのキャストと考えることができます。char から int へのキャスト、short から int へのキャスト、float から double へのキャストはすべてプロモーションです。
- 変換: long から int、int から unsigned int などへのキャストが可能です。原則として、情報が失われる可能性があります。
-1
たとえば、署名されていない型付きオブジェクトに a を割り当てるとどうなるかについてのルールがあります。場合によっては、間違った変換により未定義の動作が発生する可能性があります。float が格納できるサイズよりも大きな double を float に割り当てた場合、動作は定義されません。
あなたのキャストを見てみましょう:
int i = 10;
unsigned int k = (unsigned int) i; // :1
float fl = 10.123;
unsigned int ufl = (unsigned int) fl; // :2
char *p = "Stackoverflow Rocks";
unsigned char *up = (unsigned char *) p; // :3
- このキャストにより、変換が発生します。によって 10 が格納されることが保証されているため、データの損失は発生しません
unsigned int
。整数が負の場合、値は基本的に unsigned int の最大値をラップします ( 4.7/2を参照)。
- 値
10.123
は 10 に切り捨てられます。ここでは、明らかに情報が失われます。10 は unsigned int に収まるため、動作が定義されます。
- これは実際にはもっと注意が必要です。まず、文字列リテラルから への非推奨の変換があります
char*
。しかし、ここではそれを無視しましょう。(ここを参照)。さらに重要なことは、署名されていない型にキャストするとどうなるでしょうか? 実際には、その結果は5.2.10/7では規定されていません (そのキャストのセマンティクスは、この場合に reinterpret_cast を使用するのと同じであることに注意してください。それが可能な唯一の C++ キャストであるため):
オブジェクトへのポインターは、異なる型のオブジェクトへのポインターに明示的に変換できます。ただし、「T1 へのポインター」型の右辺値を「T2 へのポインター」型 (ここで、T1 と T2 はオブジェクト型であり、T2 のアラインメント要件は T1 のアラインメント要件よりも厳密ではありません) に変換し、元の型に戻します。元のポインター値、そのようなポインター変換の結果は規定されていません。
したがって、char *
再度キャストして戻した後にのみ、ポインターを安全に使用できます。