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


21

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

int anInt = (int)aFloat;

または

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

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

回答:


45

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

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

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

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

static_castを使用すると、「安全」に変換できるベースタイプのみが要求されるため、reinterpret_castは任意のオブジェクトのメモリ上に必要なメモリレイアウトをマッピングするだけで、何にでも変換できるため、違いは重要です。

そのため、「フィルター」は同じではないので、コンパイラー(またはdynamic_castを使用する場合はランタイム実装)に依存している場合、特定のキャストを使用すると、Cキャストを使用するよりも明確で安全です。 、Cキャストとreinterepret_castを回避します。

これがより明確になったので、別のことがあります:static_cast、reinterpret_cast、const_cast、およびdynamic_cast を検索する方が簡単です

そして究極のポイント:彼らはいです。それが欲しかった。バグの可能性があるコード、コードのにおい、バグを生成する可能性のある「トリック」は、見苦しい外観に関連付けられている場合に追跡しやすくなります。悪いコードはいはずです。

それは「設計による」です。そしてそれにより、開発者は(本当に必要ない場合はキャストを完全に回避することで)改善できた場所と、問題はないがbutいマークを付けることでコードに「文書化」されていることを知ることができます。

新しいスタイルのキャストを導入した2番目の理由は、プログラムでCスタイルのキャストを見つけるのが非常に難しいことです。たとえば、通常のエディタまたはワードプロセッサを使用してキャストを簡単に検索することはできません。Cスタイルのキャストがこのように見えないのは、潜在的に損傷を与える可能性があるため、特に残念です。い操作にはい構文形式が必要です。この観察は、新しいスタイルのキャストの構文を選択する理由の一部でした。さらに、新しいスタイルのキャストがテンプレート表記と一致するため、プログラマーは独自のキャスト、特にランタイムチェックキャストを作成できます。

おそらく、static_castは非常にugく、入力するのが比較的難しいため、1つを使用する前によく考えますか?現代のC ++ではキャストはほとんど回避できるため、それは良いことです。

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


2
もう少しポイントがあればこれに反対票を投じますが、残念ながらできません。cスタイルのキャストはreinterpret_castと同等ではありません。検討してくださいreinterpret_cast<int>(double);。Cスタイルのキャストでdoubleをintにキャストすることは完全に可能ですが、reinterpret_castでそれを行うことはできません。Timboが既にあなたにこれを指摘しており、あなたはそれを修正すると言いましたが、4年後も間違っています。キャストを使用する必要がある完全に正当な理由があるので、それが修正されたとしても、私はまだあなたに投票します。ここでは、より良い答えがあります:stackoverflow.com/a/332086/3878168
Yay295

36

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


10
...そして、彼らはあなたが意図したことをする可能性が高いです。;-)
マッケ

7
また、入力するのがはるかに多いため、キャストを必要とせずに型を正しく修正する理由がもう1つあります。
マイケルコーネ

7
そして、それらは機能として見苦しく、コードのどこに改善点があるのか​​、ドキュメントが必要な特別なケースがあるのか​​を明らかにしています。-編集:うわー、私はこの質問に答えたのを発見しました!XD-
クライム

なぜ私はそれらを検索したいのですか?
デュプリケータ

@Deduplicatorキャストがコードベースのどこで発生しているかを知りたい理由はたくさんあります。たとえば、キャストに関連する可能性のあるバグをハンティングする場合(特にクロスプラットフォーム開発を行う場合)。
クライム

13

オプションC:「C ++スタイル」キャスト。これは、構築と区別できないためです。

int anInt = int(aFloat);

あるいは:

int anInt(aFloat);

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

  • プログラマが実行しようとした操作をより厳密に定義します。

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

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


7

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

ほとんどのキャストは適切なタイプセーフを壊しますが、C ++の方が制限が厳しいため、Cキャストを使用する場合よりもタイプセーフがわずかに少なくなります。

過負荷を強制するために(T *)NULLを使用している人を許容できます...


7

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

  1. constの適用を解除するには、常にを使用する必要がありますconst_cast。明らかな理由のため。悲しいことに、キーボードを持ち上げてプログラマーの指を壊すconstを無効にするという私のルールは承認されませんでした。
  2. プログラマーがメタルに慣れるときに慣れるビット操作スタイルのシェナンガンはどれも使用する必要がありますreinterpret_cast。これは実際にはCにはない種類のキャストです。この整数のビットが実際にはフロートのビットであると仮定します。これにより、のような不快感を回避でき(int)(*(int*)(&floatVar))ます。
  3. 単語「dynamic_cast」を入力した場合、多態性クラスの階層と設計を停止して再評価します。これらの単語を削除できるまで、クラス階層の設計の再評価を続けます。
  4. 気にしないでくださいstatic_cast

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


1
dynamic_cast完全に有効なツールです。あまり役に立ちませんが、私は認めますが、グローバル変数のようなものの悪魔からはほど遠いです。ただし、主に、Cスタイルキャストの使用に関するものであるかどうかに関する質問に回答しなかったため、私はあなたを支持しました。
DeadMG

2
@DeadMG:Cスタイルのキャストについて話しました。最後の段落全体は、static_castを優先してCスタイルのキャストを正当化します。
ニコルボーラス

「悲しいことに、キーボードを伸ばしてプログラマーの指を壊すconstを無効にするという私のルールは承認されませんでした。」技術的には、コンパイラがそれを実現することは実際には合法です。コンパイラが悪魔をあなたの鼻から飛び立たせるのは合法です。
ファラプ


3

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


CでC ++スタイルのキャストを使用しようとしても、実際には機能しません;-)
Steve314

3

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

それ以外に、特定の問題が必要な場合はC ++スタイルのキャストを使用すると言います。dynamic_castが最も一般的ですが、それでも日常的なことではないでしょう。

それ以外、およびCスタイルのキャストは、少しすっきりして読みやすくするか、最近の読者がそのキャストスタイルにどれだけ慣れているかに依存しないかもしれません。私の見解では、それはあまり重要ではなく、ほとんどが個人的な好みのものですが、Cスタイルが嫌いな人がいても驚かないでください。

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

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