const_castは、C++における型変換の特別な演算子で、ポインタや参照からconstまたはvolatile修飾子を削除または追加することができます。一般的には、元のオブジェクトがconst修飾子で定義されている場合に、非const型を期待する関数にオブジェクトを渡すために使用されます。
使用法:
const T&としてグローバルに渡ってきた場合)、const修飾子を取り除いて書き込もうとすると未定義の動作が発生します。void foo(int* p) { *p = 42; } void bar(const int* q) { // constを外す — 元のオブジェクトがconstでない場合のみ! foo(const_cast<int*>(q)); }
barにintのポインタが渡された場合、constを安全に取り除くことができます。const intの場合、書き込むと未定義動作になります。
mutableを付けます。"const_castを使用して、リテラルまたは読み取り専用メモリセグメントにあるオブジェクトのconstを取り除くことはできますか?それはどのような危険を伴いますか?"
回答: ポインタや参照からconst修飾子を取り除くことは可能ですが、リテラルや"read-only"セグメントに配置された値を変更しようとすると、未定義の動作が発生します — これはアプリケーションがクラッシュしたり、書き込みが無視されたりする可能性があります。
例:
const char* str = "hello"; char* p = const_cast<char*>(str); p[0] = 'H'; // UB: 文字列リテラルは読み取り専用メモリにあります!
歴史
プロジェクトでは、フィールドのconstを解除し、それらのフィールドに書き込んでいましたが、渡された値が実際にはconst(グローバル定数であること)であることを認識していなかったため、アプリケーションは一部のプラットフォームでセグメンテーションフォルトでクラッシュしました。
歴史
コード内でconst_castを使用してmutable修飾子のないconstメソッドを回避しました:constメソッド内でクラスのフィールドを変更しており、競合アクセス時に検出が難しいバグを引き起こしました。
歴史
STLコンテナ(例えば、const std::vector)に対する不正なconst_castの使用。その後、コンテナを修正した際には直ちにエラーが発生しないことがありますが、コンテナに対する今後の操作で予測できない動作を引き起こす可能性があります。