TopC++ 入門 › 参考 › FAQ

C++ FAQ — よくある質問 30

学習者・実務者から何度も受ける疑問に、短くズバッと答える辞典です。タイトルをクリックで解答が開きます。

QQ01. struct と class の違いは?
デフォルトのアクセス指定子だけ。struct は public、class は private。それ以外は機能的に同じ。慣例として「データ集」は struct、「振る舞いを持つ」は class。
QQ02. vector と array の使い分け?
サイズがコンパイル時に決まる → std::array<T,N>(スタック上)。実行時に決まる or 可変 → std::vector<T>(ヒープ上)。
QQ03. unique_ptr と shared_ptr の使い分け?
所有者が 1 つなら unique_ptr(9 割これでよい)。複数の所有者で「最後が消したら解放」なら shared_ptr。迷ったら unique から始める。
QQ04. auto を使いすぎるのは悪い?
型名が長いテンプレートは auto が正義。一方、int n = foo(); のように素朴な型は書いた方が読みやすいことも。原則「型が右辺から明白なら auto、そうでないなら書く」。
QQ05. push_back と emplace_back の違いは?
push_back は完成したオブジェクトを渡す。emplace_back はコンストラクタ引数を渡してその場で構築。一時値の生成が省けるぶん emplace_back が速いことが多い。
QQ06. const 参照と値渡しの使い分け?
小さい型(int, double, pointer)は値渡し(コピーが安い)。大きい型(string, vector)はconst 参照。C++17 以降で「関数内で所有権が必要」なら値渡しでmove を受ける。
QQ07. std::endl と "\n" の違いは?
endl は改行 + flush。flush は I/O コストが大きい。"\n" の方が速く、バッファが溜まったら OS/shutdown 時に自動 flush されるので普通はこれで十分。
QQ08. NULL と nullptr の違いは?
NULL は整数 0 と曖昧。C++11 以降の nullptrポインタ型として明確に扱える。常に nullptr を使う。
QQ09. 関数戻り値の型に const を付けるべき?
値戻しには付けない(コピー済みなので意味が薄い)。参照戻しには const を付けるべき場面がある(const T&)。
QQ10. C++ で GC は無いの?
無い。代わりにRAII とスマートポインタで決定論的にリソース解放する。GC が無い分、デストラクタが呼ばれる順番が予測でき、リソース(ファイル・ロック)管理に強い。
QQ11. pimpl を使うべき?
ライブラリ API でビルド時間が問題になる時のみ。小さな値クラスには過剰(ヒープ確保コスト)。詳細は 第 67 回 PImpl
QQ12. 仮想関数のコストは?
vtable を経由する間接呼び出し。現代 CPU では 1 回の予測ミス程度で、大抵のアプリでは無視できる。極度に呼び出し頻度が高い場所(ゲーム内ループ等)のみ CRTP への置換を検討。
QQ13. テンプレートは cpp に書けないの?
原則ヘッダに置く(全定義が必要)。どうしても cpp に置きたいなら明示的具体化(template class X<int>;)。面倒なので header-only が主流。
QQ14. shared_ptr は遅い?
参照カウントの増減に原子操作を使うため、コピー/破棄がやや重い。大量にコピーされる場所ではボトルネックになりうる。不要なら unique_ptr / 生参照で。
QQ15. friend って何のため?
特定のクラス/関数だけにアクセス権を与える。operator<< のような外部関数が内部メンバを見る必要があるとき使う。濫用はカプセル化の破壊。
QQ16. 多重継承は悪い?
データを持つ多重継承はひし形問題などを招き避けられがち。一方、インターフェース継承(純粋仮想だけの基底)は実用的で Java のインターフェースに近い。
QQ17. try/catch のコストは?
投げなければほぼゼロ(現代のコンパイラ)。投げるとスタック巻き戻しで高コスト。ホットパス(正常系に置く必要がない場所)に使えば問題ない。
QQ18. operator++ は i++ と ++i どっち?
値が同じでよければ前置 ++i(旧値を返す一時オブジェクトを作らない)。イテレータ等の重い型で特に効く。
QQ19. cout と printf どっちが良い?
cout は型安全だが整形が面倒。C++20 std::format / std::print は printf 風の書き心地 + 型安全。現代的には format が第一候補。
QQ20. STL のコンテナはどう選ぶ?
「ランダムアクセス + 末尾追加」→ vector。「順序不問 + 高速検索」→ unordered_map/set。「順序付き」→ map/set。「両端追加削除」→ deque。「真ん中に頻繁挿入」→ list。
QQ21. 配列と vector どっちが速い?
サイズ固定なら差は誤差。vector は少しだけ間接参照があるが、最適化で消える。現代ではほぼ常に vector で十分。
QQ22. 宣言の "*" と "&" はどこに付ける?
流派あり。Stroustrup 式はT* p(型側)、C 式はT *p(変数側)。複数宣言しないのが前提なら前者が美しい。一貫性が最重要。
QQ23. Rule of Three と Rule of Five?
「ポインタ等のリソースを持つクラス」はコピー ctor / コピー代入 / dtor の 3 つ(+ C++11 以降は move ctor / move 代入で 5 つ)を全部実装する、という原則。詳細は 第34回
QQ24. C の malloc と C++ の new の違い?
new はコンストラクタを呼ぶ+ 型付き戻り値 + 失敗時例外。malloc は生バイト確保のみ。C++ では基本 new(さらに基本は make_unique)。
QQ25. 名前空間に using namespace std; を書くのは悪?
ヘッダでは絶対 NG(そこを include した全員に波及)。cpp 側のスコープ内なら許容。グローバル cpp でも小さなツール以外は避けるべき。
QQ26. C++20 を今から学ぶべき?
concepts / ranges / modules はコードを大きく変える。最新を追うなら学ぶ価値が大きい。ただし実務では C++17 がまだベースラインなことが多い。
QQ27. C++ は難しすぎる?もっと簡単な言語もあるのでは?
用途次第。「安全 + 低レベル」を同時に欲しいなら Rust も選択肢。「可読性最優先 + 学習コスト低」なら Go / Python。C++ は既存エコシステム(ゲーム、HPC、組込、金融)とゼロオーバーヘッドで選ばれ続ける。
QQ28. なぜ C++ のコンパイルは遅い?
ヘッダが実質マクロ展開されテンプレートが毎回実体化されるため。対策は pimpl / precompiled headers / modules(C++20) / forward declaration
QQ29. 本当にstd::って書かないといけないの?
書かないと名前衝突で壊れる。大規模コードでは必須のお作法。cpp 内ローカルで using std::vector; など部分 using は許容範囲。
QQ30. 学習の次の一歩は?
① このサイトのプロジェクト制作で 1 つ作る。② Effective Modern C++ を読む。③ GitHub でオープンソースライブラリを 1 つ読む(Catch2、fmt など小さめが良い)。実践と読解の両輪で伸びる。