Programmingバックエンド開発者 / C++開発者

C++で安全な型変換(type casting)をどのように実装しますか?static_castとdynamic_castの違いは何ですか?それらはいつ使用しますか?型変換を誤るとどのようなエラーが発生するか説明してください。

Hintsage AIアシスタントで面接を突破

回答。

C++における安全な型変換(type casting)は、以下のキャスト演算子を使用して実現されます:static_castdynamic_castconst_castreinterpret_cast

  • static_cast: 互換性のある型間の通常の変換に使用され、例えば、数値型と継承関係のあるクラス間の変換(ランタイムでの型チェックなし)を行います。
  • dynamic_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が正しく機能せず、基底クラスのポインタを介してオブジェクトを削除する際にメモリリークや破損が発生しました。