231

との両方がstatic_cast、別のポインター型へのreinterpret_castキャストに対して正常に機能するようです。void*どちらか一方を優先する正当な理由はありますか?

4

8 に答える 8

184

使用static_cast: ここで行われる変換を正確に記述するのは、最も狭いキャストです。

reinterpret_cast「タイプ セーフを完全に無視し、A から B にキャストする」ことを意味するため、using の方が適しているという誤解があります。

ただし、これは実際には の効果を説明しているわけではありませんreinterpret_cast。むしろ、reinterpret_castいくつかの意味がありますが、そのすべてについて、「によって実行されるマッピングreinterpret_castは実装定義である」と言えます。[5.2.10.3]

しかし、マッピングからvoid*へのキャストの特定のケースでは、標準によって完全に明確に定義されています。T*つまり、アドレスを変更せずに型のないポインターに型を割り当てることです。

これが好まれる理由static_castです。

さらに、間違いなくもっと重要なことは、 のすべての使用reinterpret_castは実に危険であるという事実です。これは、実際には (ポインターの場合) 何かを他のものに変換するためstatic_castです。これにより、誤ってあるポインター型を別の型に強制しようとしたバグから既に救われました。

于 2008-11-21T22:58:16.670 に答える
61

は、 aを他の型のポインタにstatic_cast変換するのにより適しています。void*

static_cast実行時に動作することが必ずしも保証されていない 2 つの型の間の自然で直感的な変換がある場合に選択するキャストです。たとえば、 を使用static_castして、基底クラス ポインターを派生クラス ポインターに変換できます。これは、場合によっては意味のある変換ですが、実行時まで検証できません。同様に、 を使用して から に変換できます。static_castこれは明確に定義されていますが、実行時に精度が失われる可能性があります。intchar

reinterpret_cast一方、は、基本的に安全ではない、または移植性がない変換を行うように設計されたキャスト演算子です。たとえば、 を使用して aから anreinterpret_castに変換できます。これは、システムに≤がある場合に正しく機能します。を使用して aを an に、またはその逆に変換することもできます。これは、プラットフォーム固有のものです。これは、 s とs の特定の表現が互いに共通点を持つことが保証されていないためです。void *intsizeof (void*)sizeof (int)reinterpret_castfloat*int*floatint

要するに、キャストが論理的に意味があるが、実行時に必ずしも成功するとは限らない変換を行っていることに気付いた場合は、reinterpret_cast. static_cast実行時にキャストが機能することを事前に知っていて、コンパイラに「これが機能しない可能性があることはわかっていますが、少なくとも理にかなっており、正しく機能すると信じる理由があります。実行時に正しいことを行います。」コンパイラは、キャストが関連する型間であることを確認し、そうでない場合はコンパイル時エラーを報告します。ポインター変換でこれを行うために使用reinterpret_castすると、コンパイル時の安全性チェックが完全にバイパスされます。

dynamic_castの代わりに aを使用したい状況がいくつかありますがstatic_cast、これらのほとんどはクラス階層でのキャストを含み、(ごくまれに) に直接関係しvoid*ます。

仕様でどちらが優先されるかについては、どちらも「使用するのに適したもの」として過度に言及されていません (または、少なくとも、このように言及されているものを覚えていません)。ただし、仕様では、使いstatic_castすぎreinterpret_cast。たとえば、次のように C スタイルのキャストを使用する場合

A* ptr = (A*) myVoidPointer;

static_cast試行されたキャスト演算子の順序は、常に a の前に aを使用しようとします。これは、移植性が保証されていないreinterpret_castため、必要な動作です。reinterpret_cast

于 2011-02-16T07:28:25.123 に答える
12

これは難しい質問です。一方で、Konrad は reinterpret_cast の仕様定義について優れた点を指摘していますが、実際にはおそらく同じことを行います。一方、ポインター型間でキャストしている場合 (たとえば、char* を介してメモリ内でインデックスを作成する場合はかなり一般的です)、static_castはコンパイラ エラーを生成し、とにかく reinterpret_cast を使用することを余儀なくされます

実際には、キャスト操作の意図をより説明するため、reinterpret_castを使用します。確かに、別の演算子がポインターの再解釈のみを指定するケースを作成できますが (これにより、同じアドレスが返されることが保証されます)、標準にはありません。

于 2008-11-21T23:46:24.280 に答える
3

暗黙の変換でそれを取得した可能性が高いので、暗黙の変換に最も近いのでvoid*使用する必要があります。static_cast

于 2011-02-16T07:27:46.543 に答える
1

これに使用static_castします。他に使用する方法がない場合にのみ、最もまれなケースでのみ使用しますreinterpret_cast

于 2011-02-16T07:24:08.643 に答える
0

常に可能な限り弱いキャストを使用することをお勧めします。

reinterpret_castへのポインターをキャストするために使用できますfloat。キャストが構造を壊すほど、使用には注意が必要です。

の場合、char*いくつかの が得られるまで、c スタイルのキャストを使用しますreinterpret_pointer_cast

于 2009-12-14T09:30:45.847 に答える
-2

reinterpret_castvoid*をターゲットデータ型に強制的に変換します。安全性を保証するものではなく、基になるオブジェクトが何かである可能性があるため、プログラムがクラッシュする可能性があります。

たとえば、myclass*toを型キャストしてから、完全に異なるレイアウトを持つ可能性のあるに変換するためにvoid*使用できます。reinterpret_castyourclass*

したがって、使用することをお勧めしますstatic_cast

于 2011-02-16T07:28:10.920 に答える