デフォルト引数


概要

デフォルト引数とは、仮引数に対して初期値を設定することができる機能です。
初期値を設定された仮引数は実引数で値を渡さなくても関数の実行が可能となります。

// 書式例
戻り値の型 関数名(仮引数の型 仮引数名 = 初期値)

// 具体例
void Print(int hp = 10, int mp = 10);

void Print(int hp, int mp)
{
	printf("Hp = %d, Mp = %d\n", hp, mp);
}

int main()
{
	// Hp = 10, Mp = 10
	Print();

	// Hp = 100, Mp = 10
	Print(100);

	// Hp = 200, Mp = 300
	Print(200, 300);

	return 0;
}

実行結果:
	Hp = 10, Mp = 10
	Hp = 100, Mp = 10
	Hp = 200, Mp = 300

上のコードのようにInitPlayerParamで引数を指定しなかった場合
仮引数のhpとmpには10が代入された状態になります。

設定場所

設定場所はプロトタイプ宣言、関数定義のどちらでも可能ですが、
確認のしやすさを考えるとヘッダファイルに書かれることが多い、
プロトタイプ宣言の方に記述したほうがいいと思います。

void PrintValue(int val = 0);
void PrintStr(const char* str);

void PrintValue(int val)
{
	printf("val = %d\n", val);
}

void PrintStr(const char* str = "Hello World")
{
	if (str != nullptr)
	{
		printf("%s\n", str);
	}
}

int main()
{
	PrintValue();
	PrintStr();

	return 0;
}

実行結果:
	val = 0
	Hello World

上のコードでPrintValueが宣言、PrintStrが定義に設定していますが、
宣言と定義の両方に設定するとエラーになるので気をつけてください。

void PrintValue(int val = 0);
void PrintStr(const char* str);

void PrintValue(int val = 100)
{
	printf("val = %d\n", val);
}

void PrintStr(const char* str = "Hello World")
{
	if (str != nullptr)
	{
		printf("%s\n", str);
	}
}

int main()
{
	PrintValue();
	PrintStr(nullptr);

	return 0;
}

上のコードではPrintValueの宣言と定義にデフォルト引数を設定しており、
この状態で実行すると再定義エラーになります。

メリット

デフォルト引数はオプション機能としての引数の使用に有効です。
デフォルト引数を指定することで、標準の関数の引数指定に
オプション機能としての引数を追加することができます。

// 描画関数に拡縮と回転角度をオプションとして追加した描画関数:
void Draw(float x, float y, Image image, float angle = 0.0f, float scale = 1.0f);

上の描画関数は座標と使用する画像を指定すればそれだけ描画できますが、
描画する画像を回転させたり、拡大縮小させたりもさせれます。
ただ、回転や拡縮が頻繁に起こるわけではないのに
毎回angleとscaleに値を設定することは面倒です。
そこで、デフォルト引数を使用すれば必要な時だけangle、scaleを設定でき、
必要が無ければ設定しなくてもよくなります。

このように毎回は必要ではないけど、時々必要になる引数をデフォルト引数にすれば
関数の使いやすさが向上します。

注意点

デフォルト引数は実引数指定が確定している引数の後ろに指定しなければいけません。
以下の書き方はエラーになります。

void InitPlayerParam(int hp = 10, int mp);

「int hp = 10」のデフォルト引数が実引数指定が確定している
mpの前に来ているので、コンパイルエラーになります。
仮引数は必ず引数の末尾に指定して下さい。