Function Overloading
函数重载
通常,函数的名称反映了其主要用途。一般来说,可读的程序包含各种精心选择的标识符。有时,不同的函数用于相同的目的。例如,我们可以考虑一个计算双精度数数组平均值的函数,以及同一个函数,但用于处理整数数组。这两个函数都可以方便地称为AverageFromArray:
//+------------------------------------------------------------------+
//| The calculation of average for an array of double type |
//+------------------------------------------------------------------+
double AverageFromArray(const double & array[],int size)
{
if(size<=0) return 0.0;
double sum=0.0;
double aver;
//---
for(int i=0;i<size;i++)
{
sum+=array[i]; // Summation for the double
}
aver=sum/size; // Just divide the sum by the number
//---
Print("Calculation of the average for an array of double type");
return aver;
}
//+------------------------------------------------------------------+
//| The calculation of average for an array of int type |
//+------------------------------------------------------------------+
double AverageFromArray(const int & array[],int size)
{
if(size<=0) return 0.0;
double aver=0.0;
int sum=0;
//---
for(int i=0;i<size;i++)
{
sum+=array[i]; // Summation for the int
}
aver=(double)sum/size;// Give the amount of type double, and divide
//---
Print("Calculation of the average for an array of int type");
return aver;
}每个函数都通过Print()函数输出消息;
Print("Calculation of the average for an array of int type");编译器根据参数的类型和数量选择适当的函数。做出选择的规则被称为签名匹配算法。签名是函数声明中使用的类型列表。
示例:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
//---
int a[5]={1,2,3,4,5};
double b[5]={1.1,2.2,3.3,4.4,5.5};
double int_aver=AverageFromArray(a,5);
double double_aver=AverageFromArray(b,5);
Print("int_aver = ",int_aver," double_aver = ",double_aver);
}
//--- Result of the script
// Calculate the average for an array of int type
// Calculate the average for an array of double type
// int_aver= 3.00000000 double_aver= 3.30000000
函数重载是创建多个具有相同名称但参数不同的函数的过程。这意味着在重载的函数变体中,参数的数量和/或类型必须不同。特定的函数变体是根据调用函数时参数列表与函数声明中的参数列表的对应关系来选择的。
当调用重载函数时,编译器必须有算法来选择适当的函数。执行此选择的算法取决于存在的类型的类型转换。最佳对应关系必须是唯一的。重载函数必须在至少一种参数的所有其他变体中是最佳匹配。同时,它必须对所有其他参数也与其他变体匹配得不错。
以下是每个参数的匹配算法。
选择重载函数的算法
- 使用严格匹配(如果可能)。
- 尝试标准类型提升。
- 尝试标准类型转换。
标准类型提升比其他标准转换更好。提升是指将float转换为double,将bool、char、short或enum转换为int。类似整数类型的数组类型转换也属于类型转换。类似的类型包括:bool、char、uchar,因为这三种类型都是单字节整数;双字节整数short和ushort;4字节整数int、uint和color;long、ulong和datetime。
当然,严格匹配是最好的。为了实现这种一致性,可以使用类型转换。编译器无法处理模糊的情况。因此,不应依赖类型的细微差异和隐式转换,这会使重载函数变得不清楚。
如果有疑问,请使用显式转换以确保严格合规。
在MQL4中,重载函数的示例可以在ArrayInitialize()函数的示例中看到。
函数重载规则适用于类方法的重载。
系统函数的重载是允许的,但应注意编译器能够准确选择适当的函数。例如,我们可以以4种不同方式重载系统函数MathMax(),但只有两种变体是正确的。
示例:
// 1. overload is allowed - function differs from built-in MathMax() function in the number of parameters
double MathMax(double a,double b,double c);
// 2. overload is not allowed!
// number of parameters is different, but the last has a default value
// this leads to the concealment of the system function when calling, which is unacceptable
double MathMax(double a,double b,double c=DBL_MIN);
// 3. overload is allowed - normal overload by type of parameters a and b
double MathMax(int a,int b);
// 4. overload is not allowed!
// the number and types of parameters are the same as in original double MathMax(double a,double b)
int MathMax(double a,double b);