2024年7月16日
C++ライブラリアン
C++日本語リファレンスサイトcpprefjpを運営し、C++の最新情報を日本語で発信している。株式会社Preferred Networksに所属し、スーパーコンピュータのソフトウェア開発に携わっている。
著書として、『C++テンプレートテクニック』(SBクリエイティブ)、『C++ポケットリファレンス』(技術評論社)、『プログラミングの魔導書』(ロングゲート)。
X: @cpp_akira
GitHub: faithandbrave
こんにちは。C++日本語リファレンスサイト「cpprefjp」の運営をしている高橋 晶です。
今回は、C++の基礎を学び終えた方が、さらにC++に習熟するためにおすすめしたい書籍を紹介します。
C++は1990年代から活発に使われていて、名著と言われるC++プログラマにとって必読の書籍がたくさん発売されました。絶版になってしまったものも少なくないのですが、その価値はいまだ衰えることはありません。
2024年の現代にC++を学ぶ方にこそおすすめする書籍に加え、古くからの名著を紹介していこうと思います。
本書は、私がはじめて買ったC++の書籍です。
当時の私はお給料も少なく、技術書は1ヶ月に1冊買うのが限度でした。そのため、どの本を買うべきか時間をかけて調べた結果、本書にたどり着きました。
本書は、Better C (よりよいC言語) としてC++を使っている方向けに、C++としての作法を学び、プログラムを改善していくという内容でした。当時から仕事としてC++を使っていた私にとっては目から鱗が落ちることばかりで、貪るように本書を読んだことを覚えています。
本書を読んだことで、私が書くC++プログラムは劇的によくなりました。
それまでは、仕事で前任者が書いたC++プログラムをなんとなくマネして書いていましたが、本書を読んでからはC++プログラムの良し悪しがはっきりとわかるようになり、自分でプログラムの設計というものを考えられるようになりました。
ただし、本書はC++03 (2003年時点のC++バージョン) をベースに書かれているため、内容はどうしても古くなってしまいます。それでも、以下のような方にとっては、今でも多くの学びを得ることができるでしょう。
仕事としてC++プログラムを書く方には、当たり前に全員読んでいただきたい、必読の書籍です。
本書は、当時の最新版C++であるC++14 (2014年時点のC++バージョン) でのC++の作法や考え方を学ぶ書籍となっています。
先ほど紹介した『Effective C++ 第3版』の単純なバージョンアップではないため、両方を読む必要があります。
C++は、2011年に発行されたC++11というバージョンの以下の機能によって劇的に変わりました。
これらの機能が入ったことにより、C++プログラムの書き方が従来から大きく変わり、新たな作法に従う必要がでてきました。本書では、その新たな概念を学び、正しく使うための作法やプログラムの設計を学ぶことができます。
C++14というのは、2014年に発行されたC++11を補完するバージョンとなっていて、劇的な変化をしたC++11で不足していたちょっとした機能がたくさん入りました。
2024年の現代では、多くの外部ライブラリがC++14以上を要求するようになっています。これはつまり、多くの外部ライブラリはC++14で実装されており、それを使う側もC++14までの作法は知っておかなければならないということです。
先ほど紹介した『Effective C++ 第3版』と本書『Effective Modern C++』を読むことで、現代で要求されるC++の概念、作法、設計を学ぶことができます。
ちなみに、C++14のあとは、C++17 (2017年)、C++20 (2020年)、C++23 (2023年) と新たなバージョンが続きますが、プログラムの書き方が大きく変わる変更はそれほど入っていません。C++14までの作法を学んだら、その後は新たな機能の使い方だけ学べば新バージョンにも問題なく追従していけるでしょう。
本書は「例外安全性 (Exceptional Safety)」というものを学ぶ書籍となっています。
例外安全性とは、処理の途中で例外 (エラー) が発生した場合でも、例外から復帰した際に、プログラムが不正な状態にならないようにすることです。
これはC++に限らず、あらゆるプログラミング言語に通じる内容です。プログラムでエラーが発生する場所は必ずしも自明ではなく、あらゆる場所に可能性があります。単純なところでは、以下のような順番でプログラムを処理してしまうと、
2.で例外が発生し、その例外処理から復帰した場合に、変数aの値が変更されたあとの状態になってしまっているため、再度同じ処理を実行しようとした際に変数aにさらに変更が加えられ、意図しない動作になってしまいます。そのため、ここでは処理順を逆にする必要があります。
これは単純な例ですが、これがテンプレートを使用したジェネリックプログラミングを行う場合には、問題はさらに複雑になります。型をパラメータ化して、あらゆる型で共通の処理を行うという場合に、どこに例外が発生する可能性があるかを考えた上でプログラムを書くのは難しいことです。
本書では、例外で問題が起きうるさまざまな状況を学び、例外に対して安全なプログラムを書く方法を学ぶことができます。
ただし、本書に書かれている内容と現代のC++と比べたときに、異なっている点がひとつあります。それは、C++11で導入されたnoexceptという機能です。この機能は「noexcept(式)」とすることで、特定の操作が例外を決して発生させないかどうかをコンパイル時の真理値定数として取得できます。この機能を使うことで、より強力な例外安全性をもつプログラムを設計できるようになります。本書と合わせて、C++11のnoexcept機能を学んでみてください。
高速なプログラムを書かないのであれば、C++を使う意味はありません。本書では、高速なC++プログラムを書くためのさまざまな手法を学ぶことができます。
多くの書籍では、「高速化するのはボトルネックになる場所だけだ。それ以外の場所を高速化するのは時期尚早な最適化だ」のように論じられます。しかし本書は、「最初から速いコードを書けよ!」という強い主張をしているのが大きな特徴です。
筆者であるカート・ガンセロスは“高速化に関する正しい知識と技術をしっかり身に着けておきさえすれば、遅くて無駄なコードを書くのと同じ時間で効率的なコードを書くことができる”、というのです。この考え方に私はとても共感しました。
開発はたしかに、開発速度が最も大事で、次に技術的負債を残さないことも大事です。それゆえにパフォーマンス劣化の問題が、開発の終盤にしわ寄せとして来てしまう場合があります。しかし、開発速度を落とすことなく速いコードを書くことさえできれば、あとで高速化を考える必要すらないのです。
また、実行速度が遅いことはユーザーにとってバグも同然であり、反対に、高速化の技術をもつことは開発者にとってステータスになります。世の中にはパフォーマンスに悩んでいるプロジェクトは多くあり、高速化ができる人材は活躍の場に困ることはありません。
本書では、C++標準ライブラリでのデータ構造とアルゴリズムの選択を学ぶことはもちろん、動的メモリ確保の最適化、入出力の最適化、ループの書き方に関する改善方法に加え、CPUやメモリ、OSのAPI、コンパイラの最適化など、C++における最適化を包括的に学ぶことができます。
※本書は残念ながら絶版となっています。英語の原書、もしくは中古をお買い求めください。
プログラムを設計する際は、再利用性を考えることが重要になります。
似たようなプログラムを何度も書いていては、仕事はいつまでも終わらず、残業・休日出勤が当たり前になってしまいますね。再利用できるようプログラムを設計することで、開発はどんどんラクができるようになります。
本書は、そうしたプログラムの再利用性に関する設計を学ぶ書籍です。プログラムの単純な再利用は、さまざまな用途で共通の振る舞いをする、というだけなら比較的簡単でしょう。プログラムのコピー&ペーストをせず、同じ関数・クラスを使い回せばよいですね。
しかし、さまざまな用途で共通の機能を使っていると起こるのは、「特定の用途には処理の振る舞いを少しだけ変えたい」という要求です。
本書では、プログラムの再利用に関して、「共通性 (どんな用途にも同じ振る舞いをする)」と「可変性 (特定の用途で異なる振る舞いをする)」を分析して設計することを学びます。
C++のテンプレートというジェネリックプログラミングのための機能は、この「可変性」を表現するために便利に使うことができます。
本書を読むことで、さまざまな用途に使える柔軟性をもつ再利用性の高いプログラムを設計できるようになります。
今回は2024年現在の、入門を終えたC++プログラマが読むべきおすすめの書籍を5冊紹介しました。
C++は歴史ある言語であるため、多くのノウハウが書籍としてまとめられています。これらの本を読んだ経験は、ほかの言語でプログラミングする上でも必ず役立つはずです。
より良いC++プログラムを書き、価値の高いソフトウェアを開発するために、役立てていただければ幸いです。
関連記事
人気記事