C++における安全な型変換(type casting)は、以下のキャスト演算子を使用して実現されます:static_cast、dynamic_cast、const_cast、reinterpret_cast。
nullptrを返し、参照は例外をスローします。いつ使用するか:
dynamic_castを使用します。単純な/互換性のある型間の変換にはstatic_castを使用します。例:
struct Base { virtual ~Base() {} }; struct Derived : Base { void foo() {} }; void test_cast(Base* base) { // 下位クラスへの安全な型変換 Derived* d = dynamic_cast<Derived*>(base); if (d) { d->foo(); } }
質問: 基底クラスのオブジェクトをstatic_castを使用して派生クラスに変換することはできますか?そのオブジェクトが実際には派生クラスのインスタンスでない場合。
回答: はい、static_castはコンパイルされますが、オブジェクトが実際には派生クラスのオブジェクトでない場合は未定義の動作が発生します。dynamic_castのみがその変換の安全性を保証します。ダウンキャストにstatic_castを使用するのは、オブジェクトの実際の型が確信できる場合のみ許可されます。
物語
大規模な組込みシステムでは、親クラスと子クラスのキャストがstatic_castを介して行われていました。この場合、存在しないフィールドにアクセスしようとするとクラッシュにつながることがありました — プログラムは異なる型のメモリを解釈しようとしました。
物語
プラグインアーキテクチャの開発中、プログラマーは異なる型間のポインタキャストにreinterpret_castを使用し、ゴミを読み込んだり、DLL経由の動的変換を試みたときに実行時にクラッシュが発生したりしました。
物語
企業の総合フレームワークでは、基底クラスに仮想デストラクタを忘れたため、dynamic_castが正しく機能せず、基底クラスのポインタを介してオブジェクトを削除する際にメモリリークや破損が発生しました。