0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

#0185(2025/07/02) C++ の値渡しと参照渡し

Posted at

C++ の値渡しと参照渡し

この記事のゴール

  • 値渡し (pass‑by‑value)参照渡し (pass‑by‑reference) の振る舞いを、コードと図解で直感的に理解する
  • コピーコスト、所有権、const 修飾など実務で重要になる観点を押さえる
  • よくあるバグとベストプラクティスを先回りで学ぶ

1. 値渡しとは?

  • 関数呼び出し時に実引数のコピーを作成して渡す方式
  • 関数内で値を変更しても呼び出し元には影響しない
  • 終了時にコピーは破棄される
void increment(int x) {   // 値渡し
    ++x;                  // ここだけ 1 増える
}

int n = 5;
increment(n);
// n は 5 のまま

ポイント

  • 小さな POD 型 (int, double など) ならコピーコストは軽微
  • 大きなオブジェクト (std::vector, 自前のクラス) はムダなメモリ確保が発生しやすい

2. 参照渡しとは?

  • 引数に エイリアス (別名) を渡すイメージ
  • 関数内での変更が呼び出し元にも反映される
void increment(int& x) {  // 参照渡し
    ++x;
}

int n = 5;
increment(n);  // n == 6

参照 (&) の特徴

  • nullptr にならない (安全)
  • 初期化必須
  • 一度バインドすると別オブジェクトに付け替え不可

3. const 参照 ― “変更しない参照”

  • 読み取り専用アクセスを保証
  • 大きなオブジェクトを安全かつ高速に受け取れる
void printSize(const std::vector<int>& v) {
    std::cout << v.size() << "\n";
}

ベクトルをコピーすると O(N) だが、const& ならポインタ相当の O(1)。


4. 参照 vs ポインタ

  • ポインタ (*)nullptr 可・再代入可・算術演算可
  • 参照 は C++ 的に「より安全なポインタ」
  • モダン C++ ではまず参照を使い、必要ならスマートポインタへ
void setNull(int* p) { p = nullptr; }      // ポインタは null 可
void addOne(int* p) { ++(*p); }

5. コピーコストとムーブセマンティクス (C++11+)

  • 値渡し→コピーが高い場合はムーブで受け取るテクニック
void takeVec(std::vector<int> v);          // ① コピー
void takeVec(std::vector<int>&& v);        // ② ムーブ (Rvalue 参照)

std::move を組み合わせることで不要なコピーを回避できるが、まずは const& を基本にする。


6. よくあるミスとバグ

  • 参照渡しなのに const を付け忘れ → 関数内で誤って書き換え
  • 値渡しだと勘違いして参照を渡す → 呼び出し側のデータが変わる
  • ローカル変数の参照を返す → ぶら下がり参照 (ダングリング)
int& bad() {
    int local = 42;
    return local;   // ❌ local は関数終了で破棄
}

7. ベストプラクティス

  • 小さな型 → 値渡しで OK (int, double, bool)
  • 大きな型 or 変更しないconst&
  • 呼び出し元を更新したい → 参照渡し (&)
  • リソース移譲 → Rvalue 参照 (&&) + std::move
  • API 設計 ではコピーコストと安全性のトレードオフを明示

8. まとめ

  • 値渡しはコピー参照渡しはエイリアス
  • const を活用して 読み取り専用参照 を基本形に
  • 大きなデータ構造はコピーせず参照で渡す → パフォーマンス改善
  • ムーブセマンティクス(C++11+)を覚えるとコピーコストをさらに削減

実務で迷ったら次の順に考えよう:

  1. 引数を変更する必要がある?
  2. コピーコストは許容範囲?
  3. 読み取り専用なら const&、変更するなら &
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?