33

私はまだC++が打ち負かされないいくつかのものを提供していると感じています。ここで炎上戦争を始めるつもりはありません。C++が気に入らないという強い意見がある場合は、ここでベントしないでください。C ++の達人から、なぜ彼らがそれに固執するのかについて聞くことに興味があります。

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

編集:人々、あなたがすでに言われたことを複製していないことを確認するために、少なくとも他の応答をざっと読んでください、あなたが他の誰かが言ったことに同意するなら、それを賛成してください!

4

15 に答える 15

53

RAII /決定論的ファイナライズ。いいえ、ガベージ コレクションは、希少な共有リソースを扱っている場合にはそれほど効果的ではありません。

OS API への自由なアクセス

于 2009-01-08T05:21:09.853 に答える
39

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

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

于 2009-01-08T08:22:09.927 に答える
33

自分の足を撃つ。

これほどクリエイティブなツールを提供する言語は他にありません。ポインタ、多重継承、テンプレート、演算子のオーバーロード、およびプリプロセッサ。

足を撃つための豊富な機会も提供する素晴らしく強力な言語。

編集:私の下手なユーモアの試みが気分を害した場合はお詫び申し上げます。C++ は、私がこれまでに使用した中で最も強力な言語であると考えています。必要に応じてアセンブリ言語レベルでコーディングする機能と、必要に応じて高度な抽象化レベルでコーディングする機能を備えています。C++ は、90 年代初頭から私の主要言語です。

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

于 2009-01-08T06:23:17.450 に答える
23

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

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

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

于 2009-01-08T05:56:36.820 に答える
19

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

決定論的オブジェクトの破壊。つまり、実際のデストラクタです。希少なリソースの管理が容易になります。RAII を許可します。

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

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

于 2009-01-08T06:04:54.993 に答える
13

テンプレートを使用して式をキャッチし、必要に応じて遅延実行できる C++ の機能を称賛したいと思います。これが何のことか分からない人のために、ここに例を示します。

于 2009-01-08T06:27:58.673 に答える
10

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

多くの場合、速度は問題にならないかもしれませんが、コンポーネント ソフトウェアを作成していて、ユーザーが思いがけない複雑な方法でコンポーネントを組み合わせて物事を行う場合、インライン化と C++ の速度により、はるかに複雑な構造を作成できるようです。

于 2009-01-08T05:20:08.530 に答える
9

必要に応じてメモリ レイアウト、アラインメント、およびアクセスを完全に制御します。十分に注意すれば、非常にキャッシュに適したプログラムを作成できます。マルチプロセッサ プログラムの場合、キャッシュ コヒーレンス メカニズムによる多くの速度低下を解消することもできます。

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

于 2009-01-08T06:34:08.817 に答える
6

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

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

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

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

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

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

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

于 2009-09-01T15:19:02.930 に答える
5

C#とJavaでは、「main()」関数をクラスに配置する必要があります。それはクラスの意味を薄めるので、私はそれが奇妙だと思います。

私にとって、クラスは問題のドメイン内のオブジェクトのカテゴリです。プログラムはそのようなオブジェクトではありません。したがって、プログラムに「Program」というクラスが含まれることはありません。これは、数学的対象を表す記号と一緒にそれ自体を表記する記号(証明)を使用する数学的証明と同等です。それはただ奇妙で一貫性がないでしょう。

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

于 2009-01-08T07:34:42.923 に答える
5

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

于 2009-01-08T08:38:50.547 に答える
3

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

于 2009-01-08T05:20:03.273 に答える
2

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

  1. 簡単に到達できるメモリに厳密な上限があります(物理メモリが不足すると遅くなるPCとは対照的です)
  2. 多くの場合、メモリ レイアウトが均一ではありません。あるタイプのオブジェクトを物理メモリの 1 つの部分に割り当て、別のタイプのオブジェクトを別の部分に割り当てたい場合があります。
  3. リアルタイム プログラミングの制約があります。ガベージ コレクターを間違ったタイミングで予期せず呼び出すと、悲惨な結果になる可能性があります。

私の知る限り、CとC ++は、この種のことを行うための唯一の賢明なオプションです。

于 2009-01-09T06:49:47.677 に答える
2

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

于 2009-01-08T15:57:55.530 に答える
-1

正直に言うと、十分なコードを書こうと思えば、ほぼ何でもできます。

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

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

編集: また、これが負荷の高い質問であることも認識しています。

于 2009-01-08T16:09:51.667 に答える