モダンC++入門

パフォーマンスと抽象化を両立する —— C++の真価

このページで学ぶこと

  • モダンC++(C++11以降)の安全性と生産性
  • レガシーC++との決別
  • ゼロ・オーバーヘッド(Zero Overhead)の原則
コンパイル
ソースコードを機械語に変換する処理。実行前にエラーを検出できる。
ポインタ

メモリ上のアドレスを指す変数。C++では「スマートポインタ」で安全に扱う。

RAII

リソース取得と初期化を一体化し、スコープを抜けたら自動解放する設計パターン。

STL

Standard Template Library。vector, map, algorithmなど便利な部品群。

メタファー:錆びた手斧と電動ツール

C++は「電動ツール」に進化した

Legacy C++ (~03) は「錆びた手斧」です。


手動で力任せに切る必要があり、扱いを誤るとすぐに自分の足を傷つけます(メモリリーク、セグメンテーション違反)。

Modern C++ (11~) は「最新の電動ツール」です。


安全装置(スマートポインタ)とガイド(型推論)がついており、 誰でも安全に、かつ手作業では不可能なスピードで作業できます。


「C++は難しい・危険」というイメージの大半は、錆びた手斧時代の記憶です。

C++の真価:Zero Overhead Principle

使わない機能にコストはかからない

C++には「Don’t pay for what you don’t use」という大原則があります。


抽象化(クラスや関数で包むこと)をしても、コンパイラが究極まで最適化するため、実行速度は「ベタ書き」したC言語と変わりません。

書き換えマップ:Legacy vs Modern

C++は進化の早い言語です。インターネット上の古い記事(C++98/03)を参考にすると、かえって遠回りになります。

古い書き方 (Legacy)現代の書き方 (Modern)理由
raw pointer (*)smart pointer自動でメモリ解放(GCいらず)
#defineconstexpr / inline型安全、デバッグ可能
NULLnullptr明確なポインタ型として扱える
typedefusingテンプレートに対応、読みやすい
C-array ([])std::vector / std::array境界チェック、便利なメソッド
for (int i...)range-based forインデックス管理ミス撲滅

アンチパターン:C言語のノリで書かない

C++は「C with Classes(クラス付きのC)」ではありません。全く別の言語だと思ってください。

Bad (Legacy C-Style)
// void* や printf は型安全ではない
void* ptr = malloc(sizeof(int) * 10);
printf("Value: %d", *(int*)ptr);
free(ptr); // 忘れるとメモリリーク
Good (Modern C++)
// vector と iostream を使う
std::vector<int> vec(10);
std::cout << "Value: " << vec[0] << std::endl;
// 自動でメモリ解放される

次のステップ