C++: 関数のオーバーロード
最終更新:2026-08-31
オーバーロードはC++の強力な機能——同じ名前の関数を複数定義できるが、パラメータが異なる必要がある。これでコードが読みやすく、柔軟になる。
1. オーバーロードとは何か?
(1) 1.1 定義
関数オーバーロードは、同じ名前で異なるパラメータリストを持つ複数の関数を作成できる機能。
(2) 1.2 なぜオーバーロードを使う?
TEXT
📖 参照専用
// オーバーロードなし
int addInt(int a, int b) { return a + b; }
double addDouble(double a, double b) { return a + b; }
std::string addString(std::string a, std::string b) { return a + b; }
// オーバーロードあり
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
std::string add(std::string a, std::string b) { return a + b; }
💡 ヒント: オーバーロードはコードを一貫したAPIにする——利用者は
add()を呼び出すだけで、コンパイラが正しい版を選ぶ。
2. オーバーロードのルール
(1) 2.1 何が異なる必要がある?
パラメータリストが異なる必要がある:
- パラメータの数
- パラメータの型
- パラメータの順序
(2) 2.2 何は異なっていてもいい?
戻り型だけの違いはオーバーロードではない:
CPP
int getValue() { return 42; }
double getValue() { return 3.14; } // ❌ エラー: 戻り型だけの違いは無効
3. オーバーロードの解決
コンパイラは最も一致する関数を選ぶ:
(1) 3.1 完全一致
TEXT
📖 参照専用
void print(int x);
void print(double x);
print(10); // print(int)を呼び出し
print(3.14); // print(double)を呼び出し
(2) 3.2 型変換
CPP
void print(int x);
void print(double x);
print('A'); // 'A'はintに変換 → print(int)
print(10L); // longはintまたはdoubleに変換可能 → あいまい!
4. よくある問題
(1) 4.1 あいまいな呼び出し
TEXT
📖 参照専用
void func(int x);
void func(double x);
func(10L); // ❌ エラー: longはintとdoubleの両方に変換可能
(2) 4.2 デフォルト引数との競合
CPP
void func(int x);
void func(int x, int y = 0);
func(5); // ❌ エラー: どちらも呼び出し可能
▶ サンプル 1:オーバーロードで面積計算(難易度 ⭐)
CPP
#include <iostream>
// 正方形の面積
double area(double side) {
return side * side;
}
// 長方形の面積
double area(double width, double height) {
return width * height;
}
// 円の面積
double area(double radius, bool isCircle) {
return 3.14159 * radius * radius;
}
int main() {
std::cout << "正方形: " << area(5.0) << std::endl;
std::cout << "長方形: " << area(3.0, 4.0) << std::endl;
std::cout << "円: " << area(2.0, true) << std::endl;
return 0;
}
▶ サンプル 2:異なる型で最大値(難易度 ⭐⭐)
CPP
#include <iostream>
#include <string>
int max(int a, int b) {
return (a > b) ? a : b;
}
double max(double a, double b) {
return (a > b) ? a : b;
}
std::string max(const std::string& a, const std::string& b) {
return (a > b) ? a : b; // 辞書順比較
}
int main() {
std::cout << "整数最大: " << max(10, 20) << std::endl;
std::cout << "小数最大: " << max(3.14, 2.86) << std::endl;
std::cout << "文字列最大: " << max("apple", "banana") << std::endl;
return 0;
}
▶ サンプル 3:異なるデータ型を出力(難易度 ⭐)
CPP
#include <iostream>
#include <string>
void print(int value) {
std::cout << "整数: " << value << std::endl;
}
void print(double value) {
std::cout << "小数: " << value << std::endl;
}
void print(const std::string& value) {
std::cout << "文字列: " << value << std::endl;
}
int main() {
print(42); // 整数版を呼び出し
print(3.14); // 小数版を呼び出し
print("Hello"); // 文字列版を呼び出し
return 0;
}
❓ よくある質問
Q デフォルト引数とオーバーロードを組み合わせられる?
A 注意が必要。デフォルト引数はオーバーロードと競合する可能性がある。あいまいさを避けるため、どちらかを選ぶ。
Q C言語でオーバーロードは可能?
A いいえ。オーバーロードはC++の機能。C言語では異なる名前を使う必要がある。
Q 演算子もオーバーロードできる?
A はい!演算子オーバーロードは高度なトピックで、カスタム型で
+、-、<<などの演算子を定義できる。📖 まとめ
- オーバーロードは同じ名前で異なるパラメータを持つ関数を定義
- パラメータリスト(数、型、順序)が異なる必要がある
- 戻り型だけの違いはオーバーロードにならない
- コンパイラが呼び出し時の引数に基づいて正しい版を選ぶ
- あいまいな呼び出しやデフォルト引数との競合に注意
📝 練習問題
-
初級(難易度 ⭐): 3つの
print関数をオーバーロードで作成:int、double、std::stringを出力。 -
中級(難易度 ⭐⭐): 3つの版の
absolute関数を作成:int、double、longの絶対値を返す。 -
上級(難易度 ⭐⭐⭐): 様々な型の配列の和を計算するオーバーロード関数群を作成。