他の言語では難しすぎる、または面倒なC ++でできることは何ですか?

StackOverflow https://stackoverflow.com/questions/423335

  •  05-07-2019
  •  | 
  •  

質問

私はまだ、C ++が打ち負かすことのできないものを提供していると感じています。 C ++を好まないという強い意見がある場合は、ここでフレームウォーを開始するつもりはありません。私はC ++の達人から、なぜ彼らがそれに固執するのかを聞きたいと思っています。

私は、C ++のほとんど知られていない、または十分に活用されていない側面に特に興味があります。

編集:人々、少なくとも他の回答を大まかに読んで、既に話されていることを複製しないようにしてください。

役に立ちましたか?

解決

C ++は、効率を 複雑さの組み合わせを必要とするアプリケーション向けの最高性能の汎用言語であるため、C ++に留まりました。例として、測量業界向けのハンドヘルドデバイス用のリアルタイムサーフェスモデリングソフトウェアを作成します。リソースが限られているため、Java、C#などは必要なパフォーマンス特性を提供しませんが、Cのような低レベル言語は、抽象化特性が弱いため、開発がはるかに遅くなります。 C ++開発者が利用できる抽象化のレベルの範囲は非常に広く、極端な場合は、数値を実行しながら MaterialVolume = DesignSurface-GroundSurface のように言うことができるように算術演算子をオーバーロードすることができます特定のデバイスでアプリのメモリを最も効率的に管理するためのさまざまなヒープの。これを、ほとんどすべての一般的な問題を解決するための無料で入手可能な豊富なソースと組み合わせると、強力な開発言語の1つが手に入ります。

C ++は、ほとんどのドメインのほとんどの問題に最適な開発ソリューションですか?おそらくそうではありませんが、ピンチではほとんどの人に使用できます。高性能アプリケーションの効率的な開発に最適なソリューションですか?間違いなく私見。

他のヒント

RAII /確定的ファイナライズ。いいえ、ごくわずかな共有リソースを扱う場合、ガベージコレクションは同じくらい良いではありません。

OS APIへの自由なアクセス

足で撮影する。

このような創造的なツールを提供する言語は他にありません。ポインター、多重継承、テンプレート、オペレーターのオーバーロード、およびプリプロセッサー。

フットシューティングの豊富な機会も提供する、非常に強力な言語。

編集:ユーモアの不自由な試みがいくつかの問題を引き起こした場合、私は謝ります。 C ++は、これまで使用した中で最も強力な言語であり、必要に応じてアセンブリ言語レベルで、必要に応じて高レベルの抽象化でコーディングできる機能であると考えています。 90年代初期からC ++が私の主要言語でした。

私の答えは、自分を足で撃った長年の経験に基づいていました。少なくともC ++を使用すると、エレガントに行うことができます。

確定的なオブジェクトの破壊は、いくつかの素晴らしいデザインパターンにつながります。たとえば、RAIIはガベージコレクションほど一般的な手法ではありませんが、GCでは得られない優れた機能につながります。

C ++は、チューリング完全なプリプロセッサを備えているという点でもユニークです。これにより、実行時ではなくコンパイル時の多くのコードタスクを優先することができます(延期の反対)。たとえば、実際のコードでは、発生しないことをテストするassert()ステートメントを使用できます。現実には、それは遅かれ早かれ起こるだろう...そして休暇中の午前3時に起こる。 C ++プリプロセッサのアサートは、コンパイル時に同じテストを実行します。コンパイル時のアサートは、コードのビルドを監視しているコンピューターの前にいる間、午前8:00から午後5:00の間に失敗します。ハワイで眠っている午前3時に実行時アサートが失敗します。そこでの勝利を見るのはとても簡単です。

ほとんどの言語では、戦略パターンは実行時に行われ、型が一致しない場合に例外をスローします。 C ++では、プリプロセッサ機能を使用してコンパイル時に戦略を実行でき、型保証が保証されます。

インラインアセンブリ(MMX、SSEなど)を記述します。

確定的なオブジェクトの破壊。つまり実際のデストラクタ。乏しいリソースの管理を簡単にします。 RAIIを許可します。

構造化されたバイナリデータへの簡単なアクセス。メモリ領域を構造体としてキャストし、解析して各値を構造体にコピーするよりも簡単です。

複数の継承。インターフェイスですべてができるわけではありません。実際の機能も継承したい場合があります。

テンプレートを使用して式をキャッチし、必要なときにそれを遅延して実行する機能について、C ++を賞賛するつもりだと思います。これが何であるかを知らない人のために、こちらが例です。

テンプレートミックスインは、他では見たことのない再利用を提供します。それらを使用すると、まるですべてを手で書いたかのように、多くの動作を備えた大きなオブジェクトを構築できます。しかし、その機能のこれらの小さな側面はすべて再利用できます。これは、多くのインターフェースを実装するインターフェースの一部(または全体)を実装するのに特に優れています。結果のオブジェクトはすべてインライン化されているため、非常に高速です。

速度は多くの場合重要ではないかもしれませんが、コンポーネントソフトウェアを作成している場合、ユーザーは考えられない複雑な方法でコンポーネントを組み合わせて物事を行うことができます。作成されました。

必要に応じて、メモリレイアウト、アライメント、アクセスを完全に制御できます。十分に注意すれば、非常にキャッシュに優しいプログラムを書くことができます。マルチプロセッサプログラムの場合、キャッシュコヒーレンスメカニズムによる多くのスローダウンを排除することもできます。

(さて、これはC、アセンブリ、そしておそらくFortranでもできます。しかしC ++では、プログラムの残りの部分をより高いレベルで書くことができます。)

これはおそらく一般的な答えではないでしょうが、C ++を際立たせるのはコンパイル時の機能だと思います。テンプレートと#define。これらの機能を使用して、プログラム上であらゆる種類のテキスト操作を行うことができます。これらの機能の多くは、単純化のために後の言語で廃止されました。私にとっては、C ++で簡単または高速であると思われる低レベルのビットをいじるよりもずっと重要です。

たとえば、

C#には、実際のマクロ機能はありません。別のファイルをソースに直接#includeしたり、#defineを使用してプログラムをテキストとして操作したりすることはできません。繰り返しコードを機械的に入力する必要があり、より良い方法があることを知っていたときはいつでも考えてください。コードを生成するプログラムを作成している場合もあります。さて、C ++プリプロセッサはこれらすべてを自動化します。

" generics" C#の機能は、C ++テンプレートと比較して同様に制限されています。 C ++では、ドット演算子をテンプレートタイプTに盲目的に適用し、存在しない可能性のあるメソッド(たとえば)を呼び出したり、テンプレートが実際に特定のクラスに適用された後にのみチェックを適用できます。その場合、Tについて行ったすべての仮定が実際に成り立つ場合、コードがコンパイルされます。 C#はこれを許可しません... type" T"基本的にはオブジェクトとして処理する必要があります。つまり、すべてに使用可能な操作の最も一般的な分母(割り当て、GetHashCode()、Equals())のみを使用する必要があります。

C#は、シンプルさの名の下に、プリプロセッサと実際のジェネリックを廃止しました。残念ながら、C#を使用すると、これらのC ++コンストラクトの代替物に手を伸ばすことになります。たとえば、プログラマーが#includeの不在を回避するために、いくつかの肥大化した方法で作業しています:外部アセンブリへの動的リンク、複数の場所での定数の再定義(プロジェクトごとに1ファイル)、データベースからの定数の選択など

ザ・シンプソンズのクラブアップルさんがかつて言ったように、これは「かなり不自由なミルハウス」です

コンピューターサイエンスの観点では、これらのC ++のコンパイル時機能により、名前によるパラメーターの受け渡しなどが可能になります。これは、値による呼び出しや参照による呼び出しよりも強力であることが知られています。

繰り返しますが、これはおそらく一般的な答えではありません。たとえば、C ++の入門テキストでは#defineについて警告されます。しかし、長年にわたって多種多様な言語で作業し、このすべての背後にある理論を考慮してきたため、多くの人々が悪いアドバイスを与えていると思います。これは、特に「IT」として知られる希釈されたサブフィールドの場合に当てはまるようです。

技術的には、実際には何もないと思います!

正直なところ、C ++でできることは D言語ではできないとは思いません。 C ++の能力に関係なく、Dや他の言語よりも常に難しくて厄介です。クラス宣言のような単純なものでさえ、C ++では他のどの言語よりもはるかに難しく、厄介です。

C ++でできることは、すでにC ++で記述された数百万行のコードと互換性があることです。
これは、C ++以外の言語ではできない唯一のことです:

最小限のオーバーヘッドでプロセス間でPOD構造を渡す。つまり、バイナリデータの塊を簡単に処理できます。

C#とJavaは、「main()」関数をクラスに配置することを強制します。クラスの意味を薄めるので、私はそれを奇妙に感じます。

クラスとは、問題のドメイン内のオブジェクトのカテゴリです。プログラムはそのようなオブジェクトではありません 。したがって、プログラムに「プログラム」と呼ばれるクラスがあってはなりません。これは、数学オブジェクトを表すシンボルと一緒に、それ自体を表記するためのシンボルを使用する数学的な証明-証明-と同等です。奇妙で一貫性のないものになります。

幸いなことに、C#やJavaとは異なり、C ++ではグローバル関数を使用できます。これにより、main()関数を外部に存在させることができます。したがって、C ++は、オブジェクト指向のイディオムのよりシンプルで一貫性のある、おそらくより真の実装を提供します。したがって、これはC ++でできることの1つですが、C#とJavaではできません。

演算子のオーバーロードは非常に便利な機能だと思います。もちろん、それは非常に乱用される可能性があります(Boost lambdaのように)。

オプションで強力な抽象化メカニズムを提供しながら、システムリソース(特にメモリ)を厳密に制御します。この点で私が知っている唯一の言語は、A ++です。

C ++はメモリに対する完全な制御を提供し、その結果、プログラム実行の流れをはるかに予測可能にします。 メモリの割り当てと割り当て解除がいつ発生するかを正確に言うことができるだけでなく、独自のヒープを定義し、さまざまな目的のために複数のヒープを持ち、メモリのどこにデータを割り当てるかを正確に言うことができます。これは、ゲームコンソール、携帯電話、mp3プレーヤーなどの組み込み/リアルタイムシステムでプログラミングする場合に便利です。

  1. 到達しやすいメモリには厳密な上限があります(物理メモリを使い果たすと遅くなるだけのPCとは対照的です)
  2. メモリレイアウトが均一でないことがよくあります。あるタイプのオブジェクトを1つの物理メモリに割り当て、別のタイプのオブジェクトを別のピースに割り当てることができます。
  3. リアルタイムプログラミングの制約があります。間違ったタイミングでガベージコレクターを呼び出すと、悲惨な結果になる可能性があります。

AFAIK、C、およびC ++は、この種のことを行うための唯一の賢明なオプションです。

非常に正直に言うと、十分なコードを記述したい場合は何でもできます。

それで、あなたの質問に答えるために、いいえ、C ++ができない他の言語でできないことは何もありません。それはあなたがどれだけ忍耐を持っているか、そしてあなたはそれを機能させるために長い眠れない夜を捧げることをいとわないでしょうか?

Office開発のように、C ++ラッパーを使用すると簡単にできます(ヘッダーファイルを読み取ることができるため)。しかし、繰り返しますが、それは誰かが「ラップ」するためにたくさんのコードを書いたからです。 RCWまたは" Runtime Callable Wrapper"

であなたのために

編集:また、これはロードされた質問であることがわかります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top