====== 🎯 第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` で二重インクルードを防止
----