1. ホーム
  2. c++

[解決済み] static_cast, dynamic_cast, const_cast, reinterpret_cast はいつ使うべきですか?

2022-03-17 02:03:06

質問

の正しい使い方を教えてください。

  • static_cast
  • dynamic_cast
  • const_cast
  • reinterpret_cast
  • C言語キャスト (type)value
  • 関数型キャスト type(value)

具体的にどのようなケースでどれを使うかは、どのように決めるのですか?

どのように解決するのですか?

static_cast は、最初に使おうとするキャストです。これは型間の暗黙の変換のようなことを行います(例えば int から float へのポインター void* )、明示的な変換関数(または暗黙的な変換関数)を呼び出すことができる。多くの場合,明示的に static_cast は必要ないのですが、注意点として T(something) の構文と同等です。 (T)something であり、避けるべきである(詳しくは後述)。A T(something, something_else) は安全で、コンストラクタを呼び出すことが保証されています。

static_cast は、継承階層を通過してキャストすることもできます。上方へのキャスト (基底クラスへのキャスト) では不要ですが、下方へのキャストでは virtual を継承します。ただし、チェックはしません。 static_cast 階層を下って、実際にはオブジェクトの型ではない型を指定します。


const_cast を削除または追加するために使用することができます。 const を削除できるC++のキャストは他にありません。 reinterpret_cast ). 注意すべきは、以前の const の値が未定義であるのは、元の変数が const ; もし、それを使って const で宣言されていないものへの参照は除外されます。 const であれば、安全です。に基づいてメンバ関数をオーバーロードするときに便利です。 const 例えば また const をオブジェクトに追加し、メンバ関数のオーバーロードを呼び出すことができます。

const_cast についても同様に動作します。 volatile しかし、これはあまり一般的ではありません。


dynamic_cast はポリモーフィズムを処理するためにのみ使用されます。多相型へのポインタや参照を他のクラス型にキャストすることができます(多相型は宣言または継承された少なくとも1つの仮想関数を持っています).この機能は,単に下にキャストするだけでなく,横にキャストしたり,別のチェーンにキャストしたりすることもできます.そのため dynamic_cast は目的のオブジェクトを探し出し、可能であればそれを返します。見つからない場合は nullptr ポインタの場合は std::bad_cast は、参照の場合です。

dynamic_cast には、いくつかの制限があります。同じ型のオブジェクトが継承階層に複数ある場合 (いわゆる「恐ろしいダイヤモンド」) はうまくいきません。 virtual を継承します。また、publicな継承を通過することしかできません。 protected または private を継承しています。しかし、このような形式の継承はまれであるため、問題になることはほとんどありません。


reinterpret_cast は最も危険なキャストで、あまり使用しないようにしましょう。例えば、あるポインタから別のポインタに値をキャストしたり、ポインタを int などなど、いろいろと厄介です。大きくは reinterpret_cast は、通常、結果を元の型にキャストして戻せば、まったく同じ値が得られるということです(ただし ない 中間型が元の型より小さい場合)。という変換が多数あります。 reinterpret_cast もできません。これは主に、生のデータストリームを実際のデータに変えたり、整列されたデータへのポインタの下位ビットにデータを格納したりといった、特に奇妙な変換やビット操作に使用されます。


C言語キャスト 関数型キャスト を使用したキャストです。 (type)object または type(object) それぞれ機能的に同等である。これらは,以下のうち最初に成功したものと定義される。

  • const_cast
  • static_cast (ただし、アクセス制限を無視する)
  • static_cast (上記参照)であれば const_cast
  • reinterpret_cast
  • reinterpret_cast であれば const_cast

そのため、場合によっては他のキャストの代わりとして使用することができますが、に発展する可能性があるため、非常に危険です。 reinterpret_cast という確信がない限り、明示的なキャスティングが必要な場合は、後者を優先すべきです。 static_cast が成功するか reinterpret_cast は失敗します。その場合でも、より長く、より明示的な選択肢を検討してください。

C スタイルのキャストでは、アクセス制御を無視して static_cast つまり、他のキャストにはできない操作を行うことができるのです。しかし、これはほとんどごまかしであり、私の考えでは、Cスタイルのキャストを避けるべきもう1つの理由です。