static_cast <>とCスタイルのキャストの違いは何ですか?


回答:


217

C ++スタイルのキャストはコンパイラーによってチェックされます。Cスタイルのキャストはそうではなく、実行時に失敗する可能性があります。

また、c ++スタイルのキャストは簡単に検索できますが、cスタイルのキャストを検索するのは非常に困難です。

もう1つの大きな利点は、4つの異なるC ++スタイルのキャストにより、プログラマーの意図がより明確に表現されることです。

C ++を作成するときは、Cスタイルよりも常にC ++のものを使用します。


67
実行時に失敗する可能性がある唯一のキャストはdynamic_castsです。
R.マルティーニョフェルナンデス

12
C ++ reinterpret_cast <T>(U)は、Cスタイルのキャストとほぼ同じように実行時に失敗する可能性があり、それらはすべてdynamic_cast <T>(U)が失敗する方法とはかなり異なります。
クリストファー・スミス

20
˗1通常のCキャスト(int)somethingは失敗できません。int にキャストされるか、コンパイラエラーが発生します。
トマーシュZato -復活モニカ

2
C ++キャストがCキャストよりも簡単に検索される理由を詳しく説明できますか?
Minh Tran

3
@MinhTran C ++スタイルの場合、ソースファイルからキーワード「キャスト」を検索できます。しかし、Cスタイルのキャストで何ができますか?
huangzonghao

176

つまり

  1. static_cast<>() コンパイル時間チェック機能を提供しますが、C-Styleキャストは提供しません。
  2. static_cast<>() より読みやすく、C ++ソースコード内のどこにでも簡単に見つけることができますが、C_Styleキャストはありません。
  3. C ++キャストを使用すると、意図がより適切に伝達されます。

詳細な説明

静的キャストは、互換性のある型間の変換を実行します。Cスタイルのキャストに似ていますが、より制限があります。たとえば、Cスタイルのキャストでは、整数ポインターがcharを指すことができます。

char c = 10;       // 1 byte
int *p = (int*)&c; // 4 bytes

これにより、割り当てられたメモリの1バイトを指す4バイトのポインタ(4バイトのデータ型へのポインタ)になるため、このポインタに書き込むと、ランタイムエラーが発生するか、隣接するメモリが上書きされます。

*p = 5; // run-time error: stack corruption

Cスタイルのキャストとは対照的に、静的キャストを使用すると、コンパイラーはポインターとポインターのデータ型に互換性があることを確認できるため、プログラマーはコンパイル中にこの誤ったポインター割り当てをキャッチできます。

int *q = static_cast<int*>(&c); // compile-time error

C ++キャストの詳細については、このページを確認することもできます。ここをクリック


17
「4バイトポインター」の代わりに「4バイトデータ型へのポインター」を意味したと思います
iheanyi

しかし、それはint q = static_cast <int>(c);を許可します
TonyParker

3
@TonyParkerそれはその行に何も問題がないためです。
ブレーデンベスト

15

C ++キャスト演算子の比較を参照してください。

ただし、さまざまな異なるキャスト操作に同じ構文を使用すると、プログラマーの意図が不明確になる可能性があります。

さらに、大規模なコードベースで特定のタイプのキャストを見つけるのは難しい場合があります。

Cスタイルのキャストの一般性は、単純な変換だけが必要な状況ではやり過ぎになる可能性があります。パワーの異なるいくつかの異なるキャスティングオペレーターから選択する機能により、プログラマーが誤って誤った型にキャストするのを防ぐことができます。


14
struct A {};
struct B : A {};
struct C {}; 

int main()
{
    A* a = new A;    

    int i = 10;

    a = (A*) (&i); // NO ERROR! FAIL!

    //a = static_cast<A*>(&i); ERROR! SMART!

    A* b = new B;

    B* b2 = static_cast<B*>(b); // NO ERROR! SMART!

    C* c = (C*)(b); // NO ERROR! FAIL!

    //C* c = static_cast<C*>(b); ERROR! SMART!
}

5
提供するソリューションについてもう少し説明を追加して、回答を詳しく説明していただけませんか?
アバリゾン

1
その答えは、「static_casts」が型変換をチェックして、それらが階層グラフの有効なパスに沿っていることを確認していることを示していると思います。この特定の例では、AとBが階層グラフのパスを形成するため、A *からB *またはB *からA *へのキャストが許可されます。C *がパス上にないため、static_castはコンパイル時エラーを生成します。補足:A *からB *へのキャストは、実際の基になるオブジェクトに応じて、実行時にdynamic_castでNULLになる可能性があることに注意してください。
Tommy Chen

7

C / C ++のさまざまなキャストと、Cスタイルのキャストが実際に行うことを説明する素晴らしい記事:https : //anteru.net/blog/2007/12/18/200/index.html

(タイプ)変数構文を使用したCスタイルのキャスト。これまでに最悪の発明。これは、次のキャストをこの順序で実行しようとします(C ++標準、5.4 expr.castパラグラフ5も参照)

  1. const_cast
  2. static_cast
  3. static_castの後にconst_cast
  4. reinterpret_cast
  5. const_castによるreinterpret_castfollowed

5

static_castコンパイル時に、明らかに互換性のない型の間の変換ではないことを確認します。とは異なりdynamic_cast、実行時に型の互換性のチェックは行われません。また、static_cast変換は必ずしも安全ではありません。

static_cast ポインターから基本クラスへのポインターから派生クラスへのポインターへの変換、またはenumからintやfloatからintなどのネイティブ型間の変換に使用されます。

のユーザーはstatic_cast、変換が安全であることを確認する必要があります。

Cスタイルのキャストは、コンパイル時または実行時にチェックを実行しません。


3

それぞれ異なるセマンティクスを持つさまざまな種類のキャストがあるため、static_cast <>を使用すると、intからdoubleへのように、「あるタイプから別のタイプへの正当な変換を行っています」と言うことができます。単純なCスタイルのキャストは、多くのことを意味します。キャストをアップ/ダウンしていますか?ポインタを再解釈していますか?

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.