鋳造によvoid*の代わりにreinterpret_cast
-
16-09-2019 - |
質問
いくつかについて触れたいと思い書見る reinterpret_cast
直接使用できませんで鋳造void*組み合わせ static_cast
:
T1 * p1=...
void *pv=p1;
T2 * p2= static_cast<T2*>(pv);
代わりに:
T1 * p1=...
T2 * p2= reinterpret_cast<T2*>(p1);
しかしなアライメントが可能で、大きな説明はなぜこのように直接キャスト製。私は非常に感謝のばく説明したものの答えです。
かまいません。
p.s.私から何をしなければいけないかを reinterpret_cast
用いているんですが、、たいて使用することにより、より一
解決
のための型等のジュエル)"のサマーコレクショ許可され(例えばの場合 T1
はポッド-タイプと T2
は unsigned char
のアプローチ static_cast
で定義されます。
一方で、 reinterpret_cast
が完全に実装で定義されています-保証をいただきますことができるキャストポインタ型、その他のポインタ型を返すだけの元の値また、キャストポインタ型への整数型を保持するのに十分な大きのポインタ値により実施し、ニーズが存在しないで、キャストで、気軽に味わえるのです。
具体的には、まず見積もりに関連する部品の標準を重要な部品:
5.2.10[expr.解釈.キャスト]:
のマッピングを行いreinterpret_castは 実装で定義されています.【ご注意:か、又はない場合があり、表現の異なるからです。] ...ポインタをオブジェクトで明示的に変換されるポインタをオブジェクトの異なるタイプです。) ることを除けに変換するrvalue型"ポイントT1"の"ポインタT2"(T1とT2ではオブジェクト型の配列要件のT2はより厳しい方のT1)にあり、そのオリジナルタイプ金利のポインタ値 そして、このポインタ変換は不特定.
って思ったこと。
struct pod_t { int x; };
pod_t pod;
char* p = reinterpret_cast<char*>(&pod);
memset(p, 0, sizeof pod);
が効果的に指定されていません。
を説明する理由 static_cast
作品は少する話です。こちらは上記のコード書き換えを利用 static_cast
をまとめていきたいと思いが常に意図したとおりの標準:
struct pod_t { int x; };
pod_t pod;
char* p = static_cast<char*>(static_cast<void*>(&pod));
memset(p, 0, sizeof pod);
再び私の見積りの部分の基準とともに、導いてくれることになるとの結論上記すべき携帯:
3.9[。種類]:
のためのanyオブジェクト(以外の基底クラスのsubobject)カスタマーサポート/タイプTるか否かのオブジェクト開催の有効な値のタイプT、基本となるバイト(1.7)のオブジェクトをコピー配列のcharまたは符号なしchar。該当するコンテンツの配列のcharまたはunsigned charにコピーされるオブジェクトのオブジェクトは、その後継です。
のオブジェクトの表現型のオブジェクトは、配列のN unsigned char オブジェ 使われていますが、私たちはア型のオブジェクトT、N equals sizeof(T).
3.9.2[。化合物]:
物cv-資格(3.9.3)cv-tierⅱタイプ
void*
(ポインタを無効)するために使うことができ点物の未知のタイプです。Avoid*
は提出することを検討するようanyオブジェクトにポインタです。 履歴書の格cv-tierⅱ(3.9.3)void*
は同じ表現とアライメントの要件としてcv-格cv-tierⅱchar*
.
3.10[。lval]:
場合にプログラムにアクセスの格納値のオブジェクトを通じてlvalueその他の種類の動作は未定義):
- ...
- charまたは符号なしchar型.
4.10[ます。ptr]:
るrvalue型"ポインタのcv T、"ここでTはオブジェクト型に変換することができrvalueのタイプ"のポインタを履歴書は無効となるものとする。" の結果に変換する"ポインタのcv T"、"ポインタのcv voidポイント"開始の保管場所の型のオブジェクトT住している場合、オブジェクトは最も由来のオブジェクト(1.8)のシリコーンコーティング処理を行は、基底クラスsubobject).
5.2.9[expr.します。キャスト]:
の逆の標準変換シーケンス(第4章)、その他のlvalueにrvalue(4.1)、配列-topointer(4.2)、関数へのポインタ(4.3)、boolean(4.12)コンバージョンが可能で明示的に使用static_cast.
[編集] 一方、お客様から選ばれている逸品:
9.2[クラスです。mem]/17:
ポインタをポッド-structオブジェクトを、適切に変換を用いreinterpret_cast、ポイントがその初期会員(またはその委員は、ビットフィールド、そしてユニットに所在す)。【ご注意:あ そのため 無名でパディング内のポッド-structオブジェクトなので初めて達成に必要な適切なアライメントを実施します。]
うことを意味するも reinterpret_cast
の間にポインタなんだか意味"同じアドレス".行きます。
他のヒント
意図は両方の形式が明確に定義されていることですが、言葉遣いはそれをキャプチャするために失敗したことを少しでも疑いがありません。
両方の形式は、実際に動作します。
reinterpret_cast
が意図についてより明確であり、好ましいすべきである。
これがそうである本当の理由は、C ++での継承を定義する方法の、およびのでメンバーポインタである。
Cでは、ポインタはそれがあるべきように、ほとんどただのアドレスです。 C ++では、それは、その機能のいくつかのより複雑にする必要があります。
メンバポインタが本当に彼らは常にCスタイルを使用して、災害でキャスト、クラスにオフセットされます。
あなたが多重にも、いくつかの具体的な部分を持つ2つの仮想オブジェクトを継承している場合は、、それはまた、Cスタイルのための災害です。これは、しかし、すべての問題の原因となる多重継承の場合であるので、あなたは今まで、とにかくこれを使いたくないはずです。
本当にうまくいけば、あなたは最初の場所でこれらのケースを使用することはありません。また、あなたはあなたのデザインの中にめちゃくちゃにされている別の兆候だ多くをキャストしている場合。
私はキャストを終わるだけの時間は、C ++が決定した地域でプリミティブである同じですが、どこ明らかに、彼らがする必要がありません。あなたが最も時間の「インターフェイスへのプログラミング」でなければなりませんので、実際のオブジェクトでは、あなたが何かをキャストしたい任意の時間は、あなたのデザインを疑問視し始めます。もちろん、あなたはパーティーのAPIを使用すると、常に多くの選択肢を持っていないので、どのように働くか第三変更することはできません。