web-dev-qa-db-ja.com

cスタイルのキャストまたはc ++スタイルのキャスト

それで、あなたは何を使いますか?

int anInt = (int)aFloat;

または

int anInt = static_cast<int>(aFloat);
// and its brethren

そして、さらに重要なのはなぜですか?

21
bastibe

まず、これらの行は同等ではないことを理解してください。

int* anInt = (int*)aFloat; // is equivalent to

int* anInt = reinterpret_cast<int*>(aFloat); 

ここで起こっていることは、プログラマーがキャストを作成するためにできることは何でもするようコンパイラーに求めているということです。

Static_castを使用すると、変換するのに「安全」な基本型のみが要求されるため、違いは重要です。reinterpret_castは、おそらく必要なメモリレイアウトを特定のオブジェクトのメモリにマッピングするだけで、何にでも変換できます。

したがって、「フィルター」は同じではないので、コンパイラー(またはdynamic_castを使用する場合はランタイムの実装)を使用してどこで問題が発生したかを伝える場合、特定のキャストを使用する方がCキャストを使用するよりも明確で安全です。 、Cキャストとreinterepret_castを回避します。

これがより明確になったので、もう1つあります。static_cast、reinterpret_cast、const_cast、およびdynamic_castの方が検索が簡単です

そして究極のポイント:彼らは醜いです。それが欲しかった。潜在的にバグのあるコード、コードのにおい、バグを生成する可能性のある明らかな「トリ​​ック」は、醜い外観に関連付けられていると追跡が容易になります。 不正なコードは見苦しくなければなりません

それは「仕様による」です。これにより、開発者は、(本当に必要でない場合は、キャストを完全に回避することにより)どこでより良いことができるかを知ることができます。ここでは問題ありませんが、コード内で醜いものとして「マーク」することで「文書化」されています。

新しいスタイルのキャストを導入するもう1つの理由は、Cスタイルのキャストをプログラムで見つけるのが非常に難しいことです。たとえば、通常のエディタやワードプロセッサを使用してキャストを簡単に検索することはできません。 Cスタイルのキャストがこのように見えなくなることは、非常に潜在的に有害であるため、特に残念です。 醜い操作は、醜い構文形式でなければなりません。その観察は、新しいスタイルのキャストの構文を選択する理由の一部でした。もう1つの理由は、新しいスタイルのキャストがテンプレート表記と一致するためです。これにより、プログラマーは独自のキャスト、特にランタイムチェックキャストを記述できます。

おそらく、static_castは醜く、タイプするのが比較的難しいため、1つを使用する前に2度考えてしまう可能性が高いですか?最近のC++ではキャストがほとんど回避できるため、これは良いことです。

ソース:Bjarne Stroustrup(C++作成者)

47
Klaim

C++キャストはより制限的です(そのため、意図をよりよく表現し、コードのレビューをより簡単にするなど)。また、必要に応じて、検索もはるかに簡単です。

37
Bruce Stephens

オプションC:構造と区別がつかないため、「C++スタイル」のキャスト。

int anInt = int(aFloat);

あるいは:

int anInt(aFloat);

それはさておき、プリミティブを使用したこれらの些細なケースはよく理解されていますが、Cスタイルのキャストよりもx_cast <>を使用することを好みます。理由は3つあります。

  • それらは、プログラマーが実行しようとしていた操作をより狭く定義します。

  • Cスタイルのキャストでは実行できないアクションを実行できます(特に、動的継承チェーンのブランチ間でクロスキャストできるdynamic_cast <>の場合)。

  • それらは醜いです。彼らは、プログラマーが型システムに反対して働いていることを大声で宣言します。この場合、それはgoodです。

13
Kaz Dragon

C/C++スタイルのキャストに関するいくつかのルールがあります。

  1. Constの適用解除は、必ずalwaysconst_castを使用してください。明らかな理由で。悲しいことに、キーボードを近づけてプログラマーの指を壊す原因となるconstを適用しないという私のルールは承認されませんでした。
  2. プログラマーが金属に取り掛かるときに立ち上がるビット操作スタイルの悪意のあるものは、reinterpret_castを使用する必要があります。これは実際にはCにはないキャストの種類です。この整数のビットは実際には浮動小数点のビットであると仮定します。これにより、(int)(*(int*)(&floatVar))のような不快感を回避できます。
  3. dynamic_cast」という単語を入力した場合は、停止して、ポリモーフィッククラス階層とデザインを再評価してください。それらの単語を削除できるまで、クラス階層のデザインの再評価を続けます。
  4. static_castを気にしないでください。

#4の背後にある理由は、それが問題ではないということです。他のルールに当てはまらない状況は、明白であるか、実際には低レベルです。 int-to-floatのような単純な型のよく理解されている変換では、特別な構文は必要ありません。そして、もしあなたが何かの深い、醜い根性にいるなら、まあ、あなたは何かの深い、醜い根性にいる。歯、爪、そして火はすでにそれをほとんど与えていないので、「ここにドラゴンがいる」という事実に注意を引く必要はありません。

7
Nicol Bolas

Cでコードを記述する場合は、Cキャストを使用します。 C++で記述する場合は、C++キャストを使用します。

ほとんどのキャストでは適切な型安全性が損なわれますが、C++のものはより制限が厳しいため、Cキャストを使用する場合よりも型安全性が若干低下します。

(T *)NULLを使用して誰かに過負荷を強制することは許容できます...

7
CashCow

上記の投稿にあるように、C++(静的)キャストは実際には少し安全です。

さまざまな種類のキャスティングとその長所と短所についてさらに情報を調べるのは賢明なことかもしれません。

理由についての背景をもっと知るために。 。

http://en.wikipedia.org/wiki/Static_cast

http://en.wikipedia.org/wiki/Dynamic_cast

http://en.wikipedia.org/wiki/Reinterpret_cast

4
the JinX

あなたが彼らが言うことを知っているので、それは本当に私がどの言語で働いているかに依存します:ローマではローマ語を話します。したがって、私がCでプログラミングしている場合は、C機能を最大限に活用しようとしますが、C++でプログラミングしている場合は、C++機能を最大限に活用します。彼らはそれによってコードが「移植性がなくなる」と言います、私は気にしないと私は言います、私はC++でC++でプログラミングしていて、コードをコンパイルするには完全にC++互換のコンパイラが必要です。そもそも。

3
Coyote21

static_castなどは、テンプレートで使用したときにCスタイルのキャストに問題があったために発明されました。テンプレートを作成している場合、またはコードが後でテンプレートに変換される可能性がある場合は、C++スタイルのキャストを使用することをお勧めします。その理由は、C++スタイルのキャストは意図をよりよく表現するため、Cスタイルのキャストが間違った動作をする場合に、特定の型がテンプレートパラメーターとして与えられた場合に期待される結果が得られるためです。

それ以外に、特定の問題が必要な場合はC++スタイルのキャストを使用すると言います。dynamic_castが最も一般的ですが、それでもおそらく毎日のことではありません。

それ以外は、Cスタイルのキャストは少し読みやすく、読みやすくなる場合があります。あるいは、最近の読者がそのキャストスタイルにどれほど精通しているかに依存しない場合もあります。私の見解ではそれほど重要ではありませんが、主に個人的な好みですが、Cスタイルが気に入らない人がいても驚かないでください。

最後の注意-非常に多くのキャストが必要な場合、これが大きな問題である場合は、おそらく他の何かが間違っています。例外もいくつかありますが、ほとんどの高レベルのコードは多くのキャスト(ある場合)を必要としません。

3
Steve314