第64章 同姓同名

 珍しい名前でなければ、同姓同名の人というのは結構いるものです。同姓同名といっても、外見が似ていなければ簡単に見分けが付きますよね。関数も、名前が同じでも外見が似ていなければ見分けが付くはずです。というわけで、今回は名前の同じ関数についてのお話です。


 今回の要点です。


 では、いってみましょう。


 さて、絶対値を求める関数を作りたいと思います。しかし、コンピューターには厄介な問題があります。それは整数と小数の問題です。これらで別々の関数を作る必要があります。

 整数を引数に取るときには、long 型を使えば問題なさそうです。char であっても short であっても int であっても、引数の型を long にしておけば勝手に型を変換してくれるからです。char, short, int で表現できる数値は必ず long でも表現できるからです。

 同じように、小数を引数に取るときは double 型を使えば問題なさそうです。

 で、次のようになりました。

long AbsInt(long a)
{
    return a < 0 ? -a : a;
}

double AbsFloat(double a)
{
    return a < 0 ? -a : a;
}

 同じ機能だというのに、関数名に違いがありますね。同じ機能なのなら、関数名が同じでも別に構わないでしょう。しかし、そんなことはできるのでしょうか?

 次のプログラムを見て下さい。

プログラム
// Ovload1.cpp
#include <iostream.h>

// 絶対値を求める
long Abs(long a)
{
    return a < 0 ? -a : a;
}

double Abs(double a)
{
    return a < 0 ? -a : a;
}

// 入力
int Input(int& nInt, double& nDouble)
{
    cout << "整数値を入力して下さい > " << flush;
    cin >> nInt;
    if(nInt == 1)
        return 0;

    cout << "小数値を入力して下さい > " << flush;
    cin >> nDouble;
    return 1;
}

// 絶対値の表示
void DispAbs(int nInt, double nDouble)
{
    cout << nInt    << " の絶対値は " << Abs(nInt)    << "で、" << endl
         << nDouble << " の絶対値は " << Abs(nDouble) << "です。" << endl;
}

int main()
{
    int    nInt;
    double nDouble;

    while(Input(nInt, nDouble))
        DispAbs(nInt, nDouble);

    return 0;
}
実行結果例
整数値を入力して下さい > -126
小数値を入力して下さい > 0.23
-126 の絶対値は 126 で、
0.23 の絶対値は 0.23 です。
整数値を入力して下さい > 319
小数値を入力して下さい > -0.2
319 の絶対値は 319 で、
-0.2 の絶対値は 0.2 です。
整数値を入力して下さい > 1

 どうやら、うまくいったようです。何でもやってみるものですね。

 このように、同じ名前の違う関数を作ることをオーバーロードと呼びます


 さて、同姓同名で、しかも外見などの特徴が似ている人が2人いたとします。この2人を区別することはできるでしょうか? かなり難しいと思います。人間ならいろいろ特徴があるので何とか区別がつくと思いますが、これが関数となったらどうでしょうか?

 関数の外見的な特徴といえば、戻り値の型、引数の型、個数、順番くらいです。これらが全て同じ関数を2つ定義しようとしても、この2つを外見から区別することはできませんね。

int Func(){ return 0; }
int Func(){ return 1; }

 という関数があったとします。しかし、Func(); と関数を呼んだところで、このどちらが呼ばれたのか全く区別できません。なので、全く同じ戻り値の型、引数の型、個数、順番をもつ関数を2つ定義することはできません。これはオーバーロードではなく、単なる二重定義ですね。

 さて、オーバーロードの制限はもうちょっとあります。実は、戻り値の型が違っていても、引数の型が全て同じであればオーバーロードできません。

int Func(){ return 0; }
double Func(){ return 1; }

 という関数があったとします。戻り値の型が違いますが、Func(); と関数を呼んだところで、このどちらが呼ばれたのか全く区別できませんね。

 このように、戻り値の型はオーバーロードできるかどうかに影響を与えないのです。

 まとめると、引数の型、個数、順番の同じ関数を2つ定義することはできないということになります。


 あと1つだけ注意ですが、C言語ではオーバーロードはできません。できるのはC++だけです。C/C++の両方で使うようなプログラムでは、オーバーロードをしてはいけません。


 では、今回の要点です。


 次回も関数に関するお話です。では、次回まで。


第63章 参照するな | 第65章 ナマケモノ

Last update was done on 2000.7.29

この講座の著作権はロベールが保有しています