8

SO C++ FAQ を参照するstatic_cast、dynamic_cast、および reinterpret_cast はいつ使用する必要がありますか? .

const_cast は、変数に const を削除または追加するために使用され、constness を削除する唯一の信頼できる定義済みの合法的な方法です。reinterpret_cast は、型の解釈を変更するために使用されます。

const_cast のみを使用して const 変数を非 const にキャストする必要がある理由を合理的な方法で理解していますが、const_cast の代わりに reinterpret_cast を使用して constness を追加する問題の合理的な正当化を理解できません。

constness を追加するために reinterpret_cast を使用することは正気ではないことを理解していますが、constness を追加するために reinterpret_cast を使用することは、UB または潜在的な時限爆弾になるのでしょうか?

ここで私が混乱した理由は、ステートメントのためです

ほとんどの場合、reinterpret_cast で得られる唯一の保証は、結果を元の型にキャストした場合にまったく同じ値が得られるということです。

したがって、reinterpret_cast を使用して constness を追加し、結果を元の型に reinterpret_cast すると、結果は元の型に戻り、UB になるべきではありませんが、const_cast のみを使用して constness を削除する必要があるという事実に違反しています。

別の注意事項として、標準では、ケースの再解釈を使用して Constness を追加できることが保証されています。

5.2.10 キャストの再解釈 (7) ......「T1 へのポインター」型の prvalue v を「cv T2 へのポインター」型に変換すると、結果は static_cast(static_cast(v)) になります。および T2 は標準レイアウト タイプ (3.9) であり、T2 の配置要件は T1 の配置要件よりも厳密ではありません。

4

5 に答える 5

14

reinterpret_castオブジェクト内のデータの解釈を変更します。修飾子const_castを追加または削除します。constデータ表現と constness は直交しています。したがって、異なるキャスト キーワードを使用することは理にかなっています。

したがって、reinterpret_cast を使用して constness を追加し、結果を元の型に reinterpret_cast すると、結果は元の型に戻り、UB になるべきではありませんが、const_cast のみを使用して constness を削除する必要があるという事実に違反しています。

それはコンパイルさえしません:

int * n = new int;
const * const_added = reinterpret_cast<const int *>(n);
int * original_type = reinterpret_cast<int*>(const_added);
    // error: reinterpret_cast from type ‘const int*’ to type ‘int*’ casts away qualifiers
于 2013-01-11T06:16:11.700 に答える
6

で追加するだけではいけません。Aは主に次のことを行う必要があります: ポインター (または何でも) を再解釈します。constreinterpret_castreinterpret_cast

言い換えれば、const char*(char*変更できない悪い API があるため) から変更する場合は、それconst_castがあなたの友達です。それが本当に意図したすべてです。

しかし、 から に移動する必要がある場合はMyPODType*const char*が必要です。その上に をreinterpret_cast必要としないのは、ちょうど良いことです。const_cast

于 2013-01-11T06:16:52.250 に答える
1

注意すべき点が 1 つあります。変数を書き込み可能const_castにするために を使用することはできません。constその const 参照が非 const オブジェクトを参照している場合、const 参照から非 const 参照を取得するためにのみ使用できます。複雑に聞こえますか?例:

// valid:
int x;
int const& x1 = x;
const_cast<int&>(x1) = 0;
// invalid:
int const y = 42;
int const& y1 = y;
const_cast<int&>(y1) = 0;

実際には、これらの両方がコンパイルされ、「動作」することもあります。ただし、2 番目のものは未定義の動作を引き起こし、多くの場合、定数オブジェクトが読み取り専用メモリに配置されるとプログラムが終了します。

は、最も強力なキャストですreinterpret_castが、最も危険なキャストでもあるため、必要がない限り使用しないでください。void*からに移動する必要がある場合はsometype*、 を使用しますstatic_cast。反対方向に進む場合は、組み込みの暗黙的な変換を使用するか、明示的なも使用しstatic_castます。を追加または削除する場合も同様でconst、これも暗黙的に追加されます。に関しては、 C++reinterpret_castでの議論も参照してください。

ウリ

于 2013-01-11T06:48:56.137 に答える
0

ええ、ご存じのとおり、 const_cast は、特定の型から constness を削除することを意味します。

ただし、型に constness を追加する必要がある場合。そうしなければならない理由はありますか?

例えば、

void PrintAnything(void* pData)
{
    const CObject* pObject = reinterpret_cast<CObject*>(pData);
    // below is bla-bla-bla.
}

reinterpret_cast は「const」とは関係ありません。

const_cast には 2 つの意味があります。1 つは型から constness を削除することで、もう 1 つはそのコードに明示性を与えることです。C スタイルのキャストを使用してキャストすることもできますが、これは明示的ではないため、お勧めしません。

それらは同じようには機能しません。それは間違いなく違います。

于 2013-01-11T06:57:36.603 に答える
0

reinterpret_cast を const-ness に関連付けるために考えられる唯一の場所は、void ポインターを受け入れる API に const オブジェクトを渡すときです。

UINT ThreadFunction(void* param)
{
    const MyClass* ptr = reinterpret_cast<const MyClass*>(param);
}
于 2013-01-11T06:32:03.393 に答える