====== 🎯 第2回 関数と参照・オーバーロード ====== --- ===== 🏁 授業目標 ===== * C++の関数の定義・宣言・呼び出しを理解する * const参照(const &)の使い方を理解する * 関数のオーバーロードを使って柔軟な関数設計ができるようにする ---- ===== 🧠 関数の基本 ===== C++の関数は、変数や処理をひとまとめにし、複数回呼び出せる便利な構造です。 関数には **宣言(プロトタイプ)** と **定義** があり、main()より上に宣言を書き、下に定義を書くのが一般的です。 書式のイメージ: // 関数の宣言 int add(int a, int b); int main() { int result = add(3, 5); // 呼び出し return 0; } // 関数の定義 int add(int a, int b) { return a + b; } ---- ===== 🧩 const参照(const &)の基本 ===== 大きなデータをコピーせずに扱う際に便利です。 **const参照とは、実体のアドレスを受け取り、それを変更せずに利用する方法です。** ^ 種類 ^ 内容 ^ 特徴 ^ | 値渡し | 値をコピー | 安全だが遅い場合もある | | 参照渡し | 実体を直接操作 | 変更される可能性あり | | const参照 | 実体を読み取り専用で参照 | 安全で高速 | **メリット** * コピーが発生しない → 高速 * 値を変更できない → 安全 * 一時オブジェクトも受け取れる void printName(const std::string& name) { std::cout << "Hello, " << name << std::endl; } int main() { std::string s = "Taro"; printName(s); // 実体を渡す printName("Hanako"); // 一時文字列もOK } ---- ===== 授業でやったこと ===== ①print関数2個作る(値渡し)\\ ②関数内で値がコピーされていることを確認\\  (関数内で、値を変更しても、main側では\\   変更されないよ)\\ ③参照渡しを試してみる\\  関数内で*とかつけなくても値を変更可能\\  (怖い)\\ ④const+&で引数の値を変更できなくなるよ\\  ただし、コピーじゃなくアドレスで渡せる\\  しかも*とかつけなくてもアクセス可能!\\ #include #include using std::cout; using std::endl; using std::string; void printValInt(int& val);//int型引数を受け取る関数の宣言 void printName(string& name);//string型引数を受け取る関数の宣言 int main() { int v = 42; string name = "Alice"; printValInt(v);//int型引数を渡す printName(name);//string型引数を渡す return 0; } //const + &を使うことで、参照渡しの利点を活かしつつ(コピーなし) //関数内で引数の値が変更されないようにできる void printValInt(const int& val) { //val = val + 3; cout << "int型の値: " << val << endl; } void printName(const string& name) { cout << "名前: " << name << endl; } ===== ⚙️ 関数のオーバーロード ===== 同じ名前の関数を、**引数の数・型・順序の違い**で複数定義できる機能です。 **ポイント** * 戻り値の型だけの違いでは区別できない * 引数リスト(数・型・順序)を変える必要がある int area(int w, int h) { return w * h; } double area(double r) { return 3.14 * r * r; } int main() { std::cout << area(3, 4) << std::endl; // 長方形 std::cout << area(2.5) << std::endl; // 円 } --- ===== 🔎 const参照 + オーバーロード ===== L値(変数)とR値(一時オブジェクト)で利用する関数を分けることで、より安全で効率的な設計が可能です。 void print(const std::string& s) { std::cout << s << std::endl; } void print(std::string&& s) { std::cout << s << std::endl; } int main() { std::string name = "Alice"; print(name); // L値版関数が呼ばれる print("Bob"); // R値版関数が呼ばれる } ---- ===== 🏆 まとめ ===== * 関数は「処理をまとめる箱」 * const参照で安全・高速な引数渡し * オーバーロードで同じ名前の関数を使い分け ---- ===== 📁 ヘッダファイルとソースファイルの使い分け ===== C++では、関数を複数のファイルに分けて管理します。これによりプログラムの見通しが良くなり、再利用も容易になります。 **役割の違い:** ^ ファイル ^ 拡張子 ^ 主な役割 ^ | ヘッダファイル | .h または .hpp | 関数やクラスの「宣言」だけを書く | | ソースファイル | .cpp | 関数やクラスの「定義」(実際の処理)を書く | **書き方の例:** // math.h #pragma once int add(int a, int b); int sub(int a, int b); // math.cpp #include "math.h" int add(int a, int b) { return a + b; } int sub(int a, int b) { return a - b; } // main.cpp #include #include "math.h" int main() { std::cout << add(5, 3) << std::endl; std::cout << sub(5, 3) << std::endl; } 💡 **ポイント** * ヘッダには「宣言」、cppには「定義」 * 同じ関数を複数の場所で使いたいときに便利 * `#pragma once` で二重インクルードを防止 ----