web-dev-qa-db-ja.com

C ++ 11に切り替える方法は?

私はしばらくC++でプログラミングしてきましたが、主にC++の低レベルの機能を中心にしています。つまり、主にポインタと生の配列を操作することを意味します。この動作は、クラスでC++をCとして使用することとして知られていると思います。それにもかかわらず、最近Cを試したのは初めてです。 C#やJava=のような言語が、ディクショナリやリストなどの便利な標準ライブラリクラスでこれらの詳細を隠す方法に、どのように驚きましたか。

C++標準ライブラリにはベクター、マップ、文字列などの多くのコンテナーがあり、C++ 11はstd ::配列と範囲付きループを追加するだけでこれに追加されることを知っています。

これらの現代の言語機能をどのように活用するか、どの場面に適しているかを最もよく学ぶにはどうすればよいですか?最近のC++のソフトウェアエンジニアリングでは、手動によるメモリ管理がほとんど不要であることは正しいですか。

最後に、新しい標準を最大限に活用するにはどのコンパイラを使用すればよいですか? Visual Studioには優れたデバッグツールがありますが、VS2012でもC++ 11のサポートがひどいようです。

35
Overv

まず、いくつかの経験則:

  • オーバーヘッドのないスマートポインタとして_std::unique_ptr_を使用します。生のポインタをそれほど気にする必要はありません。 _std::shared_ptr_も同様にほとんどの場合不要です。共有された所有権への欲求はしばしば、そもそも所有権についての考えの欠如を裏付けています。

  • 静的長の配列には_std::array_を使用し、動的長の配列には_std::vector_を使用します。

  • 特に、汎用アルゴリズムを広範囲に使用します。

    • _<algorithm>_
    • _<numeric>_
    • _<iterator>_
    • _<functional>_
  • 読みやすさに役立つ場合は、autoおよびdecltype()を使用します。特に、物事を宣言したいが、イテレータや複雑なテンプレートタイプなど、気にしないタイプの場合は、autoを使用します。別のものの型で宣言する場合は、decltype()を使用します。

  • 可能な場合はタイプセーフにします。特定の種類の事柄に不変条件を適用するアサーションがある場合、そのロジックは型に集中化できます。そして、これは必ずしも実行時のオーバーヘッドをもたらすわけではありません。また、Cスタイルのキャスト(_(T)x_)は、より明示的(かつ検索可能)なC++スタイルのキャスト(たとえば、_static_cast_)を優先して避ける必要があることも言うまでもありません。

  • 最後に、次の3つのルールを理解します。

    • デストラクタ
    • コンストラクタをコピー
    • 代入演算子

    ムーブコンストラクタとムーブ代入演算子の追加で5のルールになっています。また、一般的な右辺値参照とコピーを回避する方法を理解します。

C++は複雑な言語であるため、allの使用方法を特徴付けることは困難です。しかし、優れたC++開発の実践は、C++ 11によって根本的に変わっていません。それでも、手動のメモリ管理よりもメモリ管理コンテナを優先する必要があります。スマートポインタを使用すると、効率的にこれを簡単に実行できます。

現代のC++は確かにほとんど手動によるメモリ管理を必要としません。C++のメモリモデルの利点は、手動ではなくdeterministicであることです。予測可能な割り当て解除により、パフォーマンスがより予測可能になります。

コンパイラーに関しては、G ++とClangはどちらもC++ 11機能の点で競争力があり、その不足に急速に追いついています。私はVisual Studioを使用していないので、それに反対することも反対することもできません。

最後に、_std::for_each_に関する注意:一般的には避けてください。

transformaccumulate、およびerase–_remove_if_は古き良き機能mapfold、およびfilter。しかし、_for_each_はより一般的であり、したがって意味がありません。ループ以外のintentは表現されません。その上、範囲ベースのforと同じ状況で使用され、ポイントフリーを使用した場合でも構文的に重いです。検討してください:

_for (const auto i : container)
    std::cout << i << '\n';

std::for_each(container.begin(), container.end(), [](int i) {
    std::cout << i << '\n';
});

for (const auto i : container)
    frobnicate(i);

std::for_each(container.begin(), container.end(), frobnicate);
_
50
Jon Purdy

出発点として:

  • 文字列に対するchar*の使用を停止します。 std::stringまたはstd::wstringを使用して、コードが短く、読みやすく、安全になることを確認してください
  • Cスタイルの配列([ ]で宣言されたもの)の使用を停止し、std::vectorまたは他の適切なコンテナークラスを使用します。 std::vectorの良い点は、それ自体の長さがわかっていること、スコープから外れたときにコンテンツがクリーンアップされること、反復が簡単で、さらに項目を追加するとサイズが大きくなることです。しかし、あなたの状況にさらにうまくいくかもしれない他のコレクションがあります。
  • std::unique_ptrを使用して、ほとんどすぐにstd::moveを学んでください。これにより、一部のコピー不可能なオブジェクトが生成される可能性があるため、遅延によりstd::shared_ptrに送信される場合があります-std::shared_ptrの本物の使用例もある場合があります
  • 以前の宣言に依存するイテレータと型を宣言する場合はautoを使用します(たとえば、以前に何かのベクトルを宣言し、今は何かを宣言している場合はautoを使用します)
  • 他のユーザーがループを注意深く読んでコレクション全体を繰り返し処理していると結論づけることができるため、可能な限り「raw for」に対してアルゴリズムとfor_eachを使用します。コンパイラが「範囲for」をサポートしている場合for_eachで使用してください。 iotagenerateaccumulatefind_ifなどの簡単なアルゴリズム呼び出しを学びます。
  • ラムダを使用する-ラムダはアルゴリズムを活用する簡単な方法です。彼らはまた、はるかに多くの扉を開きます。

どのコンパイラを使用するかについてあまり気を付けないでください。 VS2012でのC++ 11のサポートの「ひどい、ひどい」欠如は、可変型テンプレートがないことです(そうです、そうです可変型を使用するテンプレート)と{}イニシャライザはありません。私もそうしたいのですが、便利な開発ツールの使用をやめたくはありません。

std::を採用した後の2番目のことは、RAIIの検討を開始することです。いつでも

  • 開始アクション
  • アクションの開始から得た何かを伴う一連のアクション
  • 例外の場合でも発生する必要があるクリーンアップアクション

次に、コンストラクタ、多数のメンバー関数、およびデストラクタがあります。そのためのクラスを作成してください。 ctorとdtorを書く必要さえないかもしれません。 shared_ptrをクラスのメンバー変数として配置することは、RAIIの例です。メモリ管理コードは記述しませんが、インスタンスがスコープ外になると、正しいことが起こります。ファイルのクローズ、ハンドル、ロックなどの解放やコードなどをカバーするように考えを広げると、コードは単純になり、(リークを排除しながら)小さくなります。

本当に自信がある場合は、printfを削除してcoutを優先し、マクロ(#definestuff)を削除して、PIMPLのような「高度なイディオム」の学習を始めます。 Pluralsightで これに関するコース全体 を持っているので、おそらく無料トライアルを使って見ることができます。

12
Kate Gregory

これらの現代の言語機能をどのように活用するか、どの場面に適しているかを最もよく学ぶにはどうすればよいですか?

プログラミングによって。経験は学ぶための最良の方法です。

C++ 11には多くの新機能(自動、右辺値、新しいスマートポインター-いくつか例を挙げると)があります。最善のスタートは、それらを使い始めて、可能な場合はいつでも、そして興味深い記事を見つけたときはいつでも、それらについて読むことです。

最近のC++のソフトウェアエンジニアリングでは、手動によるメモリ管理がほとんど不要であることは正しいですか。

それはあなたが何をする必要があるかによります。ほとんどのアプリケーションでは、スマートポインターを使用せずに、メモリ管理を忘れることができます。それでも簡単に解決できないアプリケーションはまだあります(たとえば、新しい配置や、何らかの理由でカスタムメモリアロケーターが必要な場合など)。

Qtを使用する必要がある場合は、それらのルールをメモリ管理に使用する必要があります。

新しい標準を最大限に活用するには、どのコンパイラを使用すればよいですか?

最新の標準をサポートしているものは何でも:

ただし、すべての機能をサポートするコンパイラはありません。

3
BЈовић