11_オーバーロード

はじめに

この章では、関数の「オーバーロード(overload)」について学びます。オーバーロードとは、同じ名前の関数を引数の型や数を変えて複数定義できる仕組みです。

オーバーロードの基本(引数の型が違う例)

// 11_function_overload.cpp
#include <iostream>
using namespace std;

void print(int n) {
    cout << "整数: " << n << endl;
}

void print(string s) {
    cout << "文字列: " << s << endl;
}

int main() {
    print(10);
    print("Hello");
    return 0;
}

同じ関数名 print が2回定義されていますが、引数の型が違うため区別されます。実引数と仮引数の一致するものが呼び出されます。

引数の数が違う例

// 11_function_overload_args.cpp
#include <iostream>
using namespace std;

void greet() {
    cout << "こんにちは!" << endl;
}

void greet(string name) {
    cout << "こんにちは、" << name << " さん!" << endl;
}

int main() {
    greet();
    greet("Tanaka");
    return 0;
}

同じ関数名 greet が2回定義されていますが、引数の数が違うため区別されます。

クラス内でのオーバーロード

// 11_class_method_overload.cpp
#include <iostream>
using namespace std;

class Calc {
public:
    int add(int a, int b) {
        return a + b;
    }

    double add(double a, double b) {
        return a + b;
    }
};

int main() {
    Calc c;
    cout << c.add(3, 5) << endl;
    cout << c.add(2.5, 1.5) << endl;
    return 0;
}
ポイント:戻り値の型だけが違うものはオーバーロードとしてみなされません。引数の型か数が違う必要があります。

コーディング演習

演習1:基本コードを動かす

11_01_overload.cpp を作成し、次のコードを入力して実行しましょう。
// function_overload.cpp
#include <iostream>
using namespace std;

void print(int n) {
    cout << "整数: " << n << endl;
}

void print(string s) {
    cout << "文字列: " << s << endl;
}

int main() {
    print(10);
    print("Hello");
    return 0;
}

演習2:コードを改造する

11_01_overload.cpp をコピーして 11_02_overload_mod.cpp として保存し、次の変更を加えてみましょう:
ヒントを見る 文字列の addreturn a + b; で文字列連結ができます(C++では string 同士の + は連結です)。
クラスのメンバ関数でも、クラス外の関数と同様にオーバーロードできます。

理解度チェック

問題11-1

次のコードを実行すると何が表示されますか?

#include <iostream>
using namespace std;

void show(int n) {
    cout << "整数: " << n << endl;
}

void show(double d) {
    cout << "実数: " << d << endl;
}

int main() {
    show(5);
    show(3.14);
    return 0;
}
解説を表示 正解:イ
show(5) は int 引数の版が呼ばれ「整数: 5」、show(3.14) は double 引数の版が呼ばれ「実数: 3.14」が表示されます。

問題11-2

オーバーロードとして有効なものはどれですか?

解説を表示 正解:ウ
オーバーロードは引数の型または数が違う必要があります。戻り値の型だけの違いはオーバーロードとして認識されず、コンパイルエラーになります。

問題11-3

次の Calc クラスで c.add(3, 5) を呼ぶと何が返されますか?

class Calc {
public:
    int add(int a, int b) { return a + b; }
    double add(double a, double b) { return a + b; }
};
解説を表示 正解:ア
35 は int リテラルなので、int add(int, int) が呼ばれます。結果は int の 8 です。

問題11-4

次のコードを実行すると何が表示されますか?

void greet() { cout << "こんにちは!" << endl; }
void greet(string name) { cout << "こんにちは、" << name << " さん!" << endl; }

int main() {
    greet("Suzuki");
    return 0;
}
解説を表示 正解:ウ
"Suzuki" という string 引数を渡しているので、greet(string name) が呼ばれ「こんにちは、Suzuki さん!」が表示されます。

まとめ