—
前回は 関数のオーバーロードについて解説しました。
改めて前回の内容をおさらいをしておくと、
- 関数のオーバーロードとは、関数に複数の書式を付与することである。
- 関数をオーバーロードさせるには、関数名は同じにしつつも、引数の数やデータ型を変えた書式を設定する。
ということをお伝えしました。
今回は 関数の初期値 についてお話ししたいと思います。
関数の初期値とは?
関数を宣言・定義をする時には、引数を設定するかしないかの判断をまず行います。
その上で、引数を設定すると決めた場合は、次にそれぞれの引数に初期値を割り当てるかを決めます。
そして、初期値を割り当てた引数は、関数を呼び出す際に、引数の入力を省略することができます。
(もちろん初期値じゃない値を入力することも可能です)
//第3引数に初期値「1.5」を設定
int testFunction(int defa1,double defa2,double defa3=1.5)
{
//各引数をログ出力
Print("defa1=",defa1," defa2=",defa2," defa3=",defa3);
return defa1;
}
void OnStart()
{
//第3引数は初期値「1.5」がわり振られているので省略可能
testFunction(1,4);
}//「1,4,1.5」がログ出力される
第3引数のdefa3にだけ、「1.5」という初期値を割り振りました。
OnStart関数内でtestFunction関数を呼び出し、
第1引数に「1」、
第3引数にはなにも入力しないでMQL5 Program Fileを実行してみると・・・↓
第3引数の初期値に設定していた「1.5」がログ出力されました。
これが関数の初期値に関する基本です。
ここを出発点にして、次の項目では初期値を設定する際の注意点をいくつか挙げていきたいと思います。
引数に初期値を設定する時の注意点
複数の引数に、初期値を設定する事ができる
最初の例では、第3引数にだけ初期値を設定しましたが、複数の引数に初期値を設定することは可能です。
//第1引数に「6」,第2引数に初期値「7.8」,第3引数に初期値「1.5」を設定
int testFunction(int defa1=6,double defa2=7.8,double defa3=1.5)
{
//各引数をログ出力
Print("defa1=",defa1," defa2=",defa2," defa3=",defa3);
return defa1;
}
void OnStart()
{
//全ての引数に初期値がわり振られているので省略可能
testFunction();
}//「6,7.8,1.5」がログ出力される
第1引数~第3引数のすべてに初期値を割り振ったので、OnStart関数内でtestFunction関数を呼び出して使う際に全ての引数入力を省略することが可能です。↓
ただし、言うまでもないことかもしれませんが、初期値を設定していない関数を呼び出して使う時に、引数入力を省略すると
「wrong parameters count(パラメーター数が間違っています)」という
コンパイルエラーが発生します。
引数に初期値を設定する際の、記述順番について
引数に初期値を設定する時は、引数を記述する順番に注意が必要です。
初期値を設定しない引数から順番に()内に記述・設定していき、初期値を設定する引数は()内の一番最後に記述します。
初期値を設定する引数が複数ある場合は、まとめて()内の最後に記述します。
//〇初期値を設定する引数は最後に書く
int testFunction(int defa1,double defa2,double defa3=0.5)
//×↓このように、初期値を設定する引数→初期値を設定しない引数の順番にしない
int testFunction(int defa1=0.1,double defa2,double defa3)
//×↓このように真ん中に初期値を設定する引数がきて、最後にまた初期値を設定しない引数が来るパターンも駄目。
int testFunction(int defa1,double defa2=0.1,double defa3)
//〇初期値を設定する引数が複数ある場合は、まとめて()内の最後に記述する
int testFunction(int defa1,double defa2,double defa3=0.5,double defa3=4.5)
()内の一番最後の引数に初期値を設定をしていないのに、その前に初期値を設定した引数があると
「missing default value for parameter(引数の初期値が欠落しています)」
というコンパイルエラーが発生します。
関数呼び出し時に、引数に値を入力する時の注意点
これまでに書いてきたのは、関数宣言時に引数を初期値を設定する際の注意点でした。
(仮引数設定の注意点とも言えます)
これから書くのは、初期値を設定後、実際に関数を呼び出して使う時
(実引数設定の注意点ですね)
などで確認・復習できますのでご覧ください。
話を戻します。
//引数に初期値を設定せずに関数を宣言
string testFunction(string defa1,int defa2=0,double defa3=0.1)
{
//各引数をログ出力
Print("defa1=",defa1," defa2=",defa2," defa3=",defa3);
return defa1;
}
引数構成は
初期値を設定している引数が2(int型1)(double型1)
となっています。
これは言い換えれば、
第1引数は値の入力が必須
第2引数と第3引数は、値を省略することもできるし、初期値ではない値を入力することもできる。
ということです。
では、こんな場合はどうでしょうか?
このような場合は、
例え第2引数に初期値をそのまま使う場合でも省略せずに値を入力する必要があります。
第1引数は省略不可なので、値を入力。
↑こんな感じですね。
//引数に初期値を設定せずに関数を宣言
string testFunction(string defa1,int defa2=0,double defa3=0.1)
{
//各引数をログ出力
Print("defa1=",defa1," defa2=",defa2," defa3=",defa3);
return defa1;
}
void OnStart()
{
//引数2は初期値0だが、省略はせず入力
testFunction("引数1",0,4.6);
//引数3は初期値ではない「4.6」を入力
}//「"引数1",0,4.6」がログ出力される
なぜ、第2引数の初期値0をそのまま省略せずにわざわざ入力しなおさなければいけないのでしょうか?
試しに第2引数を省略した形で記述したものをログ出力してみましょう。↓
//引数に初期値を設定せずに関数を宣言
string testFunction(string defa1,int defa2=0,double defa3=0.1)
{
//各引数をログ出力
Print("defa1=",defa1," defa2=",defa2," defa3=",defa3);
return defa1;
}
void OnStart()
{
testFunction("引数1",4.6);
}
このサンプルコードを実行すると・・・↓
第2引数defa2には「4」という謎の数値が入っています((+_+))
これは何が起こっているか、というと
第2引数には「4.6」という数値が格納され(しかし第2引数がint型なので、小数点以下が欠損し、結果「4」がログ出力された)、第3引数には初期値の0.1が適用された
ということです。
これは、関数で初期値を持つ引数を複数使用する際、特定の引数を省略すると、その引数以降のすべての引数も省略しなければならず、そうでないと引数の値が期待通りにならない可能性がある事を示唆しています。
今回のサンプルコードで言えば、testFunction関数は宣言時に3つの引数を設定しているわけですが、
それに対して引数が2つということは、第3引数が入力を省略した、とみなすわけです。
引数が1つの場合は、2引数と第3引数が入力を省略した、とみなされます。
サンプルコードの記述はどうだったかというと・・・
testFunction("引数1",4.6);
記述した引数は2つ。
引数3つがある関数に対して、記述した引数は2つ→第3引数の記述を省略した、とみなされた
という訳です。
でも本来の意図は、
第3引数→初期値じゃない値(=4.6)を使いたかったわけです。
話が回りくどくなりましたが、それを実現するためには
という事が必要になります。↓
最初は実引数を
(“引数1″,4.6)でコンパイルし、プログラムを実行した後、
(“引数1″,0,4.6)で再コンパイルして実行したら、ログ出力結果も想定通りの
(“引数1″,0,4.6)
という結果になりました。
もし同じ関数を使う時、引数2、引数3ともに初期値を使う場合は、どうなるかというと・・・
記述必須な引数は、初期値を設定していない第1引数だけな訳ですから、第1引数だけ値を記述して、残りの第2引数、第3引数は省略すればいいわけです。↓
string testFunction(string defa1,int defa2=0,double defa3=0.1)
{
//各引数をログ出力
Print("defa1=",defa1," defa2=",defa2," defa3=",defa3);
return defa1;
}
void OnStart()
{
//第2、第3引数は初期値を使うので省略できる
testFunction("引数1");
}
コメント