C++

C 言語にオブジェクト指向などを加えた高性能言語。処理速度が求められる領域で使われる

プログラミング言語パフォーマンス
C++」の技術書を見る →

C++ とは

C++ (シープラスプラス) は、C 言語にオブジェクト指向や豊富な抽象化機能を加えて拡張した、汎用プログラミング言語だ。ハードウェアに近い低レベルな制御と、大規模開発を支える高度な言語機能を併せ持つ点が特徴で、実行速度が最重要となる領域で広く使われ続けている。

作者は Bjarne Stroustrup で、本人の記述によれば着手は 1979 年、当初の名前は「C with Classes」だった。AT&T 社内で最初の C++ が使われたのは 1983 年 8 月、C++ という名称が実際に文書へ入ったのは同年 12 月とされる。C の実行モデルをほぼそのまま引き継ぎながら、抽象化の道具を数十年かけて積み増してきた経緯が、現在の仕様の大きさにも表れている。

どこで使われるか

分野理由
ゲームエンジン描画や物理演算の高速処理
組み込み・IoT限られた資源で動かす制御
金融・科学計算大量データの高速処理
ブラウザ・OS性能が直接体験に響く基盤ソフト

「速度と制御が利益に直結する」場面ほど、C++ が選ばれやすい。

規格の通称と処理系の既定がずれる

C++ は ISO/IEC 14882 として規格化され、おおよそ 3 年周期で改訂されている。ややこしいのは通称と規格番号が一致しないことだ。標準化委員会の説明では、現行版が C++23 と呼ばれるのは技術的な作業が 2023 年 2 月に完了したためで、承認から出版までの事務手続きの都合で正式な番号は ISO/IEC 14882:2024 になっている。プログラムから見えるのは通称側で、__cplusplus202302L を返す。2026 年 8 月時点では次の C++26 が策定作業中とされている。

もう一つの落とし穴は、処理系の既定が最新規格とは限らない点だ。Apple clang 21 では規格を指定せずにコンパイルすると __cplusplus201402L (C++14) を返し、-std=c++23 を付けて初めて 202302L になる。既定に任せていると、使うつもりだった機能が無いままだったり、規格で変わった挙動に気づけなかったりする。

規格の指定が意味論まで変える例を挙げる。

#include <string>

std::string& broken() {
    std::string s = "local";
    return s;              // 関数を抜けた時点で s は破棄される
}

このコードは Apple clang 21 で -std=c++17-std=c++20 では警告 (-Wreturn-stack-address) だけで通るが、-std=c++23 ではコンパイルエラーになる。C++23 では return する名前付きローカル変数を右辺値として扱うようになり、非 const の左辺値参照に束縛できなくなったためだ。同じソースが規格の指定次第で「警告」から「エラー」へ変わる。どの版で書くのかをコンパイルオプションと CI で固定しておくことが、C++ では特に効く。

強みと代償

C++ の最大の強みは、メモリやハードウェアを細かく制御しながら高い実行性能を引き出せることだ。ガベージコレクションに頼らず、必要な瞬間に必要なだけ資源を扱える。一方この自由度は、メモリ管理を誤ればクラッシュやセキュリティ脆弱性に直結する危うさと表裏一体になる。

この危うさを安全側へ寄せる中心の仕組みが、資源の寿命をオブジェクトの寿命に結び付ける書き方だ。確保をコンストラクタで行い解放をデストラクタに任せると、途中で例外が飛んでも早期に return しても、スコープを抜ける時点で必ず解放が走る。C++11 (2011 年) で標準に入った std::unique_ptrstd::shared_ptr は、これを所有権の表明として型に載せたもので、誰が解放の責任を持つかがコードの見た目から分かるようになる。

ただし安全になるのは所有権を書いた範囲だけだ。生のポインタや参照、イテレータ、std::string_view のように所有しない参照の手段は今も残っており、指している対象が先に消えれば未定義動作になる。未定義動作の厄介さは、その場で落ちる保証が無いところにある。コンパイラは「起こらないもの」として最適化の前提に使うため、デバッグビルドでは動いてリリースビルドで壊れる、という形で表面化しうる。実務では AddressSanitizer や UndefinedBehaviorSanitizer といった検出器をテストに組み込み、たまたま動いている状態を見つける側に回るのが定石だ。

言語仕様が巨大なのは、同じ目的を達する書き方が世代ごとに積み重なっているためでもある。古い流儀の解説と新しい流儀の解説が混在するので、どの版を前提にした情報かを常に確認する必要がある。

学習と採用の指針

C++ は「とりあえず動かす」までは他言語より手間がかかるが、性能の天井が高く、計算機の動作原理を深く学べる言語でもある。採用を迷ったときは、次の 3 点で切り分けると判断しやすい。

  1. 性能要件が実測として存在するか。 ミリ秒やメモリ 1 バイトが価値を生む領域、既存のエンジンやライブラリが C++ で書かれている領域では代わりが効きにくい。逆に Web アプリや業務システムの多くは、生産性の高い言語の方が総合では速く仕上がる。
  2. メモリ安全性を担保する体制があるか。 所有権を型で書く規約と、検出器を組み込んだ継続的なテストが前提になる。それを用意できないなら、同じ低レベル領域でも所有権の検査を処理系に任せられる言語を先に検討する価値がある。
  3. どの規格で書くかを決められるか。 使える機能は処理系と規格の指定で決まる。組み込みのように処理系が固定されている場合は、言語側の前提を先に確認しておく。

書籍を選ぶときは、本文がどの版を前提にしているかを最初に確かめたい。C++11 より前を前提にした本は生のポインタと手動解放を基本に説明していることがあり、所有権を型で書く現在の流儀とは別物になる。刊行年よりも、扱っている規格の版と演習の有無で見た方が外れにくい。

この記事は役に立ちましたか?

関連用語

関連する記事