関数のオーバーロード
CoddyのC++ジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 57/104。
関数の overloadを使用すると、同じ名前で異なるパラメーターリストを持つ複数の関数を定義できます。コンパイラーは、渡した引数に基づいて正しいバージョンを選択します。これは、コンパイル時ポリモーフィズムの重要な形式です。
オーバーロードを機能させるには、関数のシグネチャが異なっていなければなりません。つまり、パラメータの数、型、またはその両方が異なる必要があります。
class Calculator {
public:
int add(int a, int b) {
return a + b;
}
double add(double a, double b) {
return a + b;
}
int add(int a, int b, int c) {
return a + b + c;
}
};
Calculator calc;
calc.add(5, 3); // add(int, int) を呼び出す
calc.add(2.5, 3.7); // add(double, double) を呼び出す
calc.add(1, 2, 3); // add(int, int, int) を呼び出すコンパイラは各呼び出しを調べ、適切なオーバーロードに対応付けます。これは完全にコンパイル時に行われるため、実行時のオーバーヘッドはありません。
重要: 戻り値の型だけでは、オーバーロードされた関数を区別できません。次のコードはコンパイラーエラーを引き起こします。
int getValue();
double getValue(); // エラー: 戻り値の型だけでオーバーロードすることはできません関数のオーバーロードによって、コードがより直感的になります。addInts、addDoubles、addThreeIntsのような別々の名前を作成する代わりに、意味のある単一の名前を使い、残りの処理をコンパイラーに任せます。
チャレンジ
簡単関数のオーバーロードの力を示すメッセージフォーマッタークラスを作成しましょう。異なる種類の入力を処理する複数の format() メソッドを持つ Formatter クラスを作成し、渡した内容に基づいてコンパイラーが適切なバージョンを選択できるようにします。
コードは2つのファイルに分けて整理します。
Formatter.h: 異なるシナリオを処理するオーバーロードされたformat()メソッドを持つFormatterクラスを定義します。- 単一の
std::stringを受け取り、Message: <text>と出力するメソッド std::stringとintの優先度レベルを受け取り、[Priority <priority>] <text>と出力するメソッドstd::stringとdoubleのタイムスタンプを受け取り、[<timestamp>s] <text>と出力するメソッド- 3つの
std::stringパラメーター(sender、receiver、message)を受け取り、From <sender> to <receiver>: <message>と出力するメソッド
format()とします。コンパイラーは引数に基づいて正しいものを選択します。- 単一の
main.cpp: 4つの入力を読み取ります(それぞれ別の行に入力します)。- 単純なメッセージテキスト
- 優先度レベル(整数)
- タイムスタンプ(double)
- 送信者名
Formatterobject を作成し、4つすべてのオーバーロードされたメソッドを実行してみます。- メッセージテキストだけを指定して
format()を呼び出す - メッセージテキストと優先度を指定して
format()を呼び出す - メッセージテキストとタイムスタンプを指定して
format()を呼び出す - sender、receiver としての "Admin"、およびメッセージテキストを指定して
format()を呼び出す
たとえば、入力が System ready、3、12.5、Server の場合:
Message: System ready
[Priority 3] System ready
[12.5s] System ready
From Server to Admin: System ready同じメソッド名 format() を4回呼び出していますが、それぞれの呼び出しでは、引数の型と数に基づいて異なるバージョンが実行されることに注目してください。これはコンパイル時ポリモーフィズムの実例です。プログラムが実行される前に、コンパイラーがどのオーバーロードを使用するかを決定します。
自分で試してみよう
#include <iostream>
#include <string>
#include "Formatter.h"
using namespace std;
int main() {
// 入力を読み取る
string message;
getline(cin, message);
int priority;
cin >> priority;
double timestamp;
cin >> timestamp;
cin.ignore();
string sender;
getline(cin, sender);
// TODO: Formatterオブジェクトを作成する
// TODO: メッセージテキストだけでformat()を呼び出す
// TODO: メッセージテキストとpriorityでformat()を呼び出す
// TODO: メッセージテキストとtimestampでformat()を呼び出す
// TODO: sender、「Admin」をreceiverとして、メッセージテキストでformat()を呼び出す
return 0;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
3コンストラクタとデストラクタ
デフォルトコンストラクタパラメータ付きコンストラクタコピーコンストラクタムーブコンストラクタコンストラクタ初期化リスト委譲コンストラクタデストラクタ徹底解説Rule of Three / Five / Zero復習 - Stringクラス6演算子オーバーロード
演算子オーバーロード入門算術演算子のオーバーロード比較演算子のオーバーロードストリーム演算子代入演算子のオーバーロード[] と () の演算子オーバーロード型変換演算子復習 - Matrixクラス自分で練習してみよう: C++オンラインコンパイラ