関数
オーバーロード (多重定義)
異なる定義を持つ複数の関数を同じ関数名で提供することを,関数のオーバーロード (overload) または多重定義といいます。
関数のオーバーロードは,関数のシグニチャ (signature) が異なれば可能です。
ここで,関数のシグニチャとは,関数名と引数型の並びのことをいいます。
次の 3 つの関数 sum は,それぞれシグニチャが異なるので,オーバーロード可能です。
int sum(int a, int b) { ... } // sum(int, int)
int sum(int a, int b, int c) { ... } // sum(int, int, int)
double sum(double a, double b) { ... } // sum(double, double)
int main()
{
sum(2, 3); // 1 番目の sum
sum(2, 3, 4); // 2 番目の sum
sum(2.0, 3.0); // 3 番目の sum
}
以下の 3 つの関数はどれも互いに同じシグニチャを持つため,オーバーロードできません.
シグニチャが同じだと,どの関数を呼び出しているかがわからないため,オーバーロードできないのは当然ですね.
int sum(int a, int b) { ...}
int sum(int x, int y) { ... } // 引数の変数名を変えてもシグニチャは同じ
double sum(int a, int b) { ... } // 返却型を変えてもシグニチャは同じ
デフォルト引数
関数の引数のうち,デフォルトの値を与えた引数をデフォルト引数といいます。
デフォルト引数は,関数の呼び出し時に省略できます。
次のプログラムは,デフォルト引数 d を持つ関数 increment を定義したものです。
#include <iostream>
int increment(int n, int d = 1)
{
return n + d;
}
int main()
{
std::cout << increment(5) << std::endl; // 出力: 6
std::cout << increment(5, -1) << std::endl; // 出力: 4
}
インライン関数
インライン関数は,コンパイル時に定義が展開される (すなわち,インライン化される) 関数です。
コンパイル時に定義が展開されるため,実行時には関数呼び出しが行われません。
関数呼び出しにかかるオーバヘッドが気になるケースで重宝します。
C++ では,関数定義に inline キーワードを付けることで,その関数をインライン関数とすることができます。
inline double square(double x)
{
return x * x;
}
インライン関数の呼び出しは,普通の関数と何ら変わりありません。
#include <iostream>
inline double square(double x)
{
return x * x;
}
int main()
{
std::cout << square(3.0) << std::endl; // 出力: 9
}
C では,インライン関数と同じようなことは関数型マクロによって実現していました。
しかし,関数型マクロはコンパイラによる型チェックを受けることもできず,また,引数に与えた式がそのまま展開されて思わぬバグを生むことがあります。
C++ でも関数型マクロを利用することはできますが,普通はインライン化関数を利用するのがよいでしょう。
#define SQUARE(x) ((x) * (x))