C++ ドキュメント
簡潔で実例中心の C++ リファレンス。概念を読み、コードを見て、Coddy のジャーニーで実践しましょう。
C++ のガイド付き学習を始めるはじめに
- C++とはC++が実際には何なのか、なぜネイティブな機械語へ直接コンパイルされるのか、そしてどんな高性能ソフトウェアの構築に使われているのか。
- C++ のインストールC++ コンパイラ(GCC、Clang、MSVC)のインストール方法、OS に合ったツールチェーンの選び方、そしてコマンドラインで動作を確認する方法を解説します。
- C++のコンパイルC++が.cppソースをネイティブな実行ファイルに変える仕組み: g++(またはclang++/MSVC)でコンパイルし、バイナリを実行し、うまくいかないときにコンパイラのエラーを読む方法。
- C++の構文C++プログラムの基本的な構文ルール(文とセミコロン、波かっこのブロック、main関数、出力の仕組み)を、最初のプログラムから読み解いて解説します。
- コメントC++でコメントを書く方法 - 1行の // メモと複数行の /* */ ブロック - に加えて、コードをコメントアウトする方法、ブロックコメントがネストできない理由、そして残す価値のあるコメントとは何か。
変数と型
- 変数C++ で変数がどのように動くか - 型を伴う宣言、代入と初期化の違い、波かっこ初期化、命名規則、そして変数がどこで生まれ消えるかを決めるスコープ。
- データ型C++の基本的なデータ型(整数、浮動小数点数、char、bool)の実践的なツアー。サイズ、signed と unsigned、リテラルとサフィックス、オーバーフロー、そして適切な型の選び方も解説します。
- auto キーワード`auto` キーワードがコンパイラに変数の型を推論させるしくみ — 何を取り除くのか、どこで真価を発揮するのか、そして初心者がはまる落とし穴。
- 定数と constC++ で const を使って読み取り専用の値を宣言する方法、const と constexpr の違い、const ポインタと const へのポインタの違い、そして const メンバ関数について解説します。
- 演算子C++の演算子(算術・比較・論理・代入・ビット演算)を学びましょう。整数除算、優先順位、短絡評価にまつわる落とし穴も解説します。
- 型キャストC++ における型キャストの仕組み——暗黙の変換、整数除算の落とし穴、4 つの名前付きキャスト(static_cast、const_cast、reinterpret_cast、dynamic_cast)——そして静かなデータ損失を招く落とし穴まで解説します。
制御フロー
- if-elseC++ で if、else if、else を使って判断する方法 — 条件、分岐の連鎖、ネスト、三項演算子、初期化子付き if、そして人がはまりやすい落とし穴。
- switchC++ の switch 文を解説:case ラベル、break とフォールスルー、default 分岐、case のグループ化、enum に対する switch、そして case 内での宣言にまつわる落とし穴。
- for ループC++ の for ループでコードを繰り返す方法 - 3 つのパートからなるヘッダー、増加・減少のカウント、配列のループ、ネスト、break と continue、そして誰もがはまる off-by-one と符号なし型のバグ。
- while ループC++ の while ループを解説:条件を先に評価する while、最低1回は実行される do-while、番兵値までのループ、break と continue、そして無限ループの避け方。
- 範囲ベース forC++ の範囲ベース for ループをわかりやすく解説。配列・vector・string・map をすっきり反復する方法、auto& や const auto& を使うべき理由、そして避けるべきコピーとイテレータ無効化の落とし穴。
関数
- 関数C++ で関数を書く方法 — 戻り値の型・名前・引数という構造、宣言と定義の違い、値を返す方法、void 関数、そして return の書き忘れやプロトタイプの忘れといった落とし穴。
- 関数パラメータ引数がC++の関数にどのように渡されるか - 値渡しと参照渡し、安全で安価な読み取り専用アクセスのためのconst参照、デフォルト引数、ポインタ、そしてプログラムを知らぬ間に遅くするコピーコストの落とし穴。
- 参照C++の参照を解説。パラメータの & がどのようにエイリアスを作るのか、参照渡しがなぜコピーを避け関数が呼び出し元の変数を変更できるようにするのか、そして値を返す代わりに const& や参照を使うべき場面を説明します。
- 関数オーバーロードC++の関数オーバーロードを使うと、引数リストが異なっていれば複数の関数が1つの名前を共有できます。オーバーロード解決がどのように一致を選ぶのか、なぜ戻り値の型だけでは区別にならないのか、そして避けるべき曖昧さとデフォルト引数の落とし穴を学びましょう。
- ラムダ式C++のラムダ式で、その場で小さなインライン関数を書く方法を解説します。構文、キャプチャの仕組み、`mutable` を使うタイミング、そして誰もがはまるダングリングキャプチャの罠まで。
ポインタとメモリ
- ポインタC++ のポインタをゼロから解説:ポインタの宣言、& (アドレス演算子)と * (参照外し演算子)、nullptr、配列へのポインタ、そしてクラッシュの原因になるダングリングポインタや未初期化ポインタの落とし穴。
- 参照とポインタC++ における参照とポインタの実践的な比較。共通点、相違点(再束縛、null、算術演算)、そして日々のコードでどちらを使うべきかの明確なルールを示します。
- 動的メモリ実行時に`new`でメモリを確保し、`delete`で解放する方法と、ヒープを手作業で管理するときに付きまとうリーク・ダングリングポインタ・二重解放を避ける方法。
- スマートポインタスマートポインタはヒープメモリを所有し、自動的に解放します。`unique_ptr`、`shared_ptr`、`make_unique`、`make_shared`を学び、なぜもう`new`/`delete`をほとんど書く必要がないのかを理解しましょう。
文字列と入出力
STL コンテナ
- 配列C++ の生配列を解説:宣言と初期化の方法、安全なインデックス指定、サイズを使ったループ、配列からポインタへの減衰という罠、そして std::array や vector が通常は優れている理由。
- vectorstd::vector は C++ のサイズ変更可能な配列であり、デフォルトで手に取るべきコンテナです。vector の作成・アクセス・拡張・ループの方法に加え、イテレータ無効化や範囲外アクセスといった落とし穴も学びましょう。
- mapC++ の std::map を解説 — 対数時間で検索できる、キーでソートされたキー・バリュー型コンテナ。挿入・検索・反復処理の方法と、キーをこっそり挿入してしまう operator[] の定番の落とし穴を回避する方法。
- unordered_mapC++ の std::unordered_map を学びましょう。平均 O(1) で挿入と検索ができる、map のハッシュテーブル版です。基本操作、[] による自動挿入の落とし穴、count と find の違い、順序付き map ではなくこちらを選ぶべき場面を扱います。
- setstd::set が C++ で一意かつ自動的にソートされた値をどう格納するか: 挿入、count や find によるメンバーシップの確認、順序どおりの反復、そして set・multiset・unordered_set の違い。
- pair と tuple`std::pair` と `std::tuple` が 2 つ以上の値を 1 つのオブジェクトにまとめる方法: 作り方、フィールドへのアクセス、構造化束縛、そしてそれぞれの使いどころ。
- イテレータC++のイテレータがコンテナへの汎用的なポインタとしてどう機能するか――begin()とend()、参照外し、前進、const/reverseの各バリアント、そして未定義動作を引き起こす無効化とend()の参照外しという落とし穴を解説します。
STL アルゴリズムとテンプレート
- アルゴリズムC++ の標準アルゴリズム - `find`、`count_if`、`transform`、`accumulate`、`remove` - を使って、手書きのループなしで範囲に対する実際の処理を行いましょう。あわせてイテレータのペアと erase-remove イディオムの落とし穴も解説します。
- ソート`std::sort`でC++のベクタや配列をソートする方法: デフォルトの順序、カスタム比較関数、構造体をフィールドでソートする方法、そしてクラッシュを招く狭義の弱順序の落とし穴。
- テンプレートC++ のテンプレートを使えば、コードを一度だけ書いてあらゆる型で動かせます。関数テンプレート、クラステンプレート、型推論、そしてそれらが引き起こす分かりにくいコンパイルエラーを解説します。
クラスとオブジェクト
- クラスC++ のクラスがデータと振る舞いを再利用可能な型にまとめる方法を学びます。メンバー変数とメソッドの宣言、オブジェクトの生成、public/private の使い分け、そして未初期化メンバーや this ポインタといった落とし穴まで。
- コンストラクタコンストラクタは、オブジェクトが生成されるときに実行される特別なメンバ関数です。デフォルトコンストラクタ、引数付きコンストラクタ、コピーコンストラクタ、メンバ初期化リスト、そしてオブジェクトを中途半端に初期化したまま放置しない方法を学びます。
- デストラクタデストラクタはオブジェクトが破棄されるときに自動的に実行されます。`~ClassName()` の構文、いつ発火するか、なぜリソースを解放するのか、そして「3の法則/5の法則」を学びましょう。
- 継承C++の継承によって、派生クラスが基底クラスを再利用・拡張できる仕組みを学びます。構文、public継承とprivate継承の違い、コンストラクタとデストラクタの順序、そしてオブジェクトスライシングなどの落とし穴まで解説します。
- 仮想関数仮想関数を使うと、基底クラスのポインタから実行時に派生クラスのメソッドを呼び出せます。`virtual`、`override`、抽象クラス、そして基底クラスのデストラクタが仮想でなければならない理由を学びましょう。
- 演算子オーバーロードC++の演算子オーバーロードを使うと、自作の型を +、==、<< といった組み込み演算子で動かせます。メンバ関数と非メンバ関数の使い分け、比較演算子とストリーム演算子のオーバーロード方法、そして戻り値の型や代入演算子にまつわる落とし穴を学びましょう。
- アクセス指定子public、private、protected が C++ でクラスのメンバーに誰が触れられるかをどう制御するか - カプセル化の基礎を、ゲッター、セッター、そして friend という抜け道とともに解説します。
- 構造体C++の構造体を解説。関連する変数を1つの型にまとめる方法、構造体オブジェクトの宣言と初期化、構造体にメンバ関数やコンストラクタを持たせる方法、そしてstructがclassと実際にどう違うのかを説明します。
- enumC++のenumを学ぼう。宣言の仕方、スコープ付きのenum classが通常のenumより安全な理由、独自の基底値、列挙子に対するswitch、そして整数との相互変換について解説します。
エラーとデバッグ
- 例外例外は、関数がその場で処理できないエラーを報告します。`throw`の使い方、標準の例外型、`what()`メッセージ、そして本当に重要な失敗において例外が戻り値より優れている理由を学びましょう。
- try-catch危険なコードを `try` で囲み、`catch` で対応します。例外を const 参照で捕捉する方法、複数のハンドラの順序、`catch (...)` の使い方、そしてリソースを漏らさずに再スローする方法を学びましょう。
- 未定義動作未定義動作(UB)とは、C++標準が一切のルールを定めていないコードのことです。クラッシュしたり、データを破壊したり、一見正常に動いたりします。よくある原因、「ちゃんと動いた」が何も証明しない理由、そしてUBを検出するツールを学びましょう。