static_castとreinterpret_castはどちらも、void *を別のポインター型にキャストする場合に正常に機能するようです。どちらか一方を他方よりも有利にする正当な理由はありますか?
static_castとreinterpret_castはどちらも、void *を別のポインター型にキャストする場合に正常に機能するようです。どちらか一方を他方よりも有利にする正当な理由はありますか?
回答:
使用static_cast
:ここで行われる変換を正確に記述するのは、最も狭いキャストです。
reinterpret_cast
「タイプセーフを完全に無視して、AからBにキャストするだけ」を意味するので、使用する方がより良い一致であるという誤解があります。
ただし、これは実際にはの効果を説明するものではありませんreinterpret_cast
。むしろ、reinterpret_cast
いくつかの意味があり、そのすべてが「によって実行されるマッピングreinterpret_cast
は実装定義である」としています。[5.2.10.3]
しかし、マッピングからvoid*
へのキャストの特定のケースでT*
は、標準によって完全に明確に定義されています。つまり、アドレスを変更せずに型なしポインターに型を割り当てることです。
これが好む理由static_cast
です。
さらに、間違いなくより重要なのは、のすべての使用がreinterpret_cast
実際に(ポインタに対して)何かに変換されるため非常に危険であるという事実ですstatic_cast
。これにより、あるポインタタイプを別のポインタタイプに誤って強制しようとしたバグから、すでに私を救っています。
これは難しい質問です。一方では、Konradはreinterpret_castの仕様定義について優れた点を示していますが、実際にはおそらく同じことを行います。一方、ポインタ型の間、あなたしているキャストの場合、(のchar *を経由してメモリ内のインデックスは、例えばとき、かなり一般的であるように)はstatic_castは、コンパイラエラーが発生しますし、使用することを余儀なくされますreinterpret_castはとにかく。
実際にはreinterpret_castを使用します。これは、キャスト操作の意図を説明するためです。別の演算子がポインターの再解釈のみを指定するようにすることもできます(同じアドレスが返されることが保証されています)が、標準にはありません。
reinterpret_cast
!
常に最も弱いキャストを使用することをお勧めします。
reinterpret_cast
へのポインタをキャストするために使用できますfloat
。キャストを構造破壊するほど、それを使用する注意が必要になります。
の場合はchar*
、reinterpret_pointer_cast
それよりも弱く、他には何も足りないので、いくつかがあるまでは、Cスタイルのキャストを使用します。
float f = *reinterpret_cast<const float*>(&p);
float
、これは誤りです。式はにキャストvoid **
しconst float *
、逆参照演算(キャストではない)を使用const float *
してに変換しfloat
ます。
私の個人的な好みは、次のようなコードリテラシーに基づいています。
void* data = something;
MyClass* foo = reinterpret_cast<MyClass*>(data);
foo->bar();
または
typedef void* hMyClass; //typedef as a handle or reference
hMyClass = something;
const MyClass& foo = static_cast<MyClass&>(*hMyClass);
foo.bar();
どちらも最終的には同じことを行いますが、ミドルウェアのアプリ環境ではstatic_castがより適切であるように見えますが、キャストの再解釈は、下位レベルのライブラリIMHOで見られるものに似ています。