[解決済み] static_cast, dynamic_cast, const_cast, reinterpret_cast はいつ使うべきですか?
質問
の正しい使い方を教えてください。
-
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つの理由です。
関連
-
[解決済み】エラー。switchステートメントでcaseラベルにジャンプする
-
[解決済み] コピーアンドスワップ慣用句とは?
-
[解決済み] スマートポインターとは何ですか?
-
[解決済み] C++11の'typedef'と'using'の違いは何ですか?
-
[解決済み] C++11のT&&(ダブルアンパサンド)の意味とは?
-
[解決済み] std::move()とは何ですか?また、どのような場合に使用するのですか?
-
[解決済み] CとC++でmain()は何を返すべきですか?
-
[解決済み] reinterpret_castはいつ使うのか?
-
[解決済み】画像処理。コカ・コーラ缶」認識のためのアルゴリズム改良
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み】 != と =! の違いと例(C++の場合)
-
[解決済み】C++エラーです。"配列は中括弧で囲まれたイニシャライザーで初期化する必要がある"
-
[解決済み】C++でランダムな2倍数を生成する
-
[解決済み】'cout'は型名ではない
-
[解決済み】C++の変数はイニシャライザーを持っているが、不完全な型?
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み】CMakeエラー at CMakeLists.txt:30 (project)。CMAKE_C_COMPILER が見つかりませんでした。
-
[解決済み] 数値定数の前にunqualified-idを付けて、数値を定義することを期待する。
-
[解決済み] レギュラーキャスト vs スタティックキャスト vs ダイナミックキャスト [重複]の比較