C++変数と定数の使い分け設計レビュー|const-correctness・スコープ設計・変更不能性を読み取るレビュー観点
この記事のポイント
- 「定数化できるか? 変数に残すべきか?」の設計判断をレビューで読み取る力をつける
 - const-correctnessをレビュー観点として捉え直す
 - スコープ・変更可能性・初期化タイミングを整理する
 
レビューの現場では「const付けましょう」と形式的に指摘される場面も多いですが、
本来は変更可能性の設計意図を読み取るレビューが重要になります。
1. 変数定義がレビュー対象になる理由
1-1. 変更可能性は設計そのものに関わる
- 誰がいつこの値を変更する想定なのか?
 - そもそも本当に変更する必要があるのか?
 - 誤って変更されないように守るべきか?
 
この判断がコードにはっきり表現されていることが大事です。
1-2. 設計意図が埋め込まれていない例
int retryCount = 3;この 3 は単なる数字ですが、
- 仕様で固定なのか
 - 環境で変わる前提なのか
 - テストで差し替える想定なのか
 
レビューアーはこういった背景を読み取る必要があります。
2. 変数定義は「管理責任の宣言」でもある
| パターン | 説明 | 
|---|---|
定数(constexpr / const) | 
変更禁止を明示して固定 | 
| 変更可能変数 | 状態変化の必要がある設計 | 
| 誤変更誘発変数 | 本来固定のはずが変更可能に残してしまった設計 | 
3. constexpr と const の使い分け
3-1. constexpr(完全固定)
- コンパイル時に値が確定するもの
 - 実行時のコストゼロ
 - 設計的にも「動かない設計」を意味する
 
constexpr int MaxRetryCount = 3;3-2. const(実行時固定)
- 実行時に決まるけれど、その後変更不可
 - 設定ファイル読込結果などに多い
 
const int RetryLimit = config.GetDefaultRetryLimit();3-3. 比較表まとめ
| 特性 | constexpr | const | |–|–| | 決定タイミング | コンパイル時 | 実行時含む | | 設計意図 | 完全固定宣言 | 実行後固定宣言 | | 最適化効果 | 高い | 状況次第 |
4. const-correctness というレビューの要所
4-1. const-correctness = 変更不能契約の宣言
class Config {
public:
  std::string GetName() const;
};- メンバ関数に 
constが付いていれば、
「この関数は状態を変更しません」 と読むことができます。 
4-2. const を付ける場所は多い
- 関数引数
 - 戻り値
 - メンバ関数自体
 - ポインタ・参照先の内容
 
void Process(const ApiRequestLog& request);- const は実装の都合ではなく、設計意図の整理結果として付くもの です。
 
5. 良い実装例:設計が整理された定義
#pragma once
#include <string>
struct ApiRequestLog {
    int requestId;
    std::string endpoint;
    std::string clientIp;
};
inline constexpr int DefaultTimeoutSeconds = 30;
class Config {
public:
    Config(const std::string& filename);
    int GetMaxRetryCount() const;
private:
    const std::string configFile;
};- 定数は 
constexpr/constを使い分けて整理 - 不変メンバには 
constを付け、設計意図を明確にしている 
6. よくある誤りとレビュー例
ケース1:本来固定なのに変数にしてしまう
int DefaultTimeoutSeconds = 30;
@Reviewer固定値ならconstexprで定数化してください
改善例
inline constexpr int DefaultTimeoutSeconds = 30;ケース2:const 漏れ(関数引数)
void Process(ApiRequestLog& request);
@Reviewer参照専用ならconstを付けて意図を明示してください
改善例
void Process(const ApiRequestLog& request);ケース3:const 漏れ(メンバ関数)
class Config {
public:
  int GetMaxRetryCount();
@Reviewer状態変更しない関数はconst指定してください};改善例
class Config {
public:
  int GetMaxRetryCount() const;
};7. PlantUMLで整理する設計責務
- 定数と可変の責務が分かれて整理されている
 - 依存も過剰にならず管理しやすい構造
 
8. CI統制:変更不能性レビューの支援ツール
clang-tidy 例
Checks: '-*,cppcoreguidelines-avoid-magic-numbers,readability-const-return-type'- マジックナンバー排除
 - const 漏れの指摘
 
include-what-you-use 活用
- 定数ヘッダーの整理でインクルード最小化も支援できる
 
PR文化としても統制
- 「constは設計意図を表す」文化をレビュー文化にする
 
9. レビュー観点チェックリスト
| 観点 | 確認すること | 
|---|---|
| 定数化できるもの | constexpr を積極的に利用しているか | 
| 実行時固定 | const で正しく固定しているか | 
| マジックナンバー排除 | 裸の数字が散らばっていないか | 
| const-correctness | 関数・引数・戻り値・メンバのconst漏れ確認 | 
| スコープ設計 | グローバル/クラス内/関数内で整理できているか | 
| ODR安全性 | inline constexpr で多翻訳単位の安全性確保 | 
| CI統制 | 自動チェックで漏れなく検出できているか | 
10. まとめ
定数と変数の設計は、実は
「誰がいつ責任を持って値を変更できるのか?」 を整理している作業でもあります。
レビューアーは「constを付けましょう」ではなく
「そもそも誰が管理する値なのか?」
という設計の背景を読み取る視点を持つことがとても重要です。
こうした読み取りができると、自然と保守性も高くなり、設計としても安定します。
