Geralmente, o nome da função tende a refletir seu propósito principal. Como regra, programas legíveis contém vários identificadores bem selecionados. Às vezes, funções diferentes são usados para os mesmos propósitos. Vamos considerar, por exemplo, uma função que calcula o valor médio de um array de números de dupla precisão e a mesma função, mas operando com um array de inteiros. Ambas são convenientemente chamadas de AverageFromArray:

//+------------------------------------------------------------------+
//| O cálculo de média de um array de tipo double |
//+------------------------------------------------------------------+
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]; // Soma para o tipo double
}
aver=sum/size; // Apenas divide a soma pelo número
//---
Print("Cálculo da média para um array do tipo double");
return aver;
}
//+------------------------------------------------------------------+
//| O cálculo de média para um array de tipo int |
//+------------------------------------------------------------------+
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]; // Soma para o tipo int
}
aver=(double)sum/size;// Fornece uma quantidade de tipo double, e divide
//---
Print("Cálculo da média para um array do tipo int");
return aver;
}

Cada função contém a saída da mensagem via a função Print();

Print("Cálculo da média para um array do tipo int");

O compilador seleciona a função necessária de acordo com os tipos dos argumentos e suas quantidades. A regra, que define a escolha a ser feita, é chamada de algoritmo de correspondência de assinatura. Um assinatura é uma lista de tipos usados na declaração da função.

Exemplo:

//+------------------------------------------------------------------+
//| Programa Script da função start (iniciar) |
//+------------------------------------------------------------------+
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);
}
//--- Resultado do script
// Calcula a média para um array de tipo int
// Calcula a média para um array de tipo double
// int_aver= 3.00000000 double_aver= 3.30000000

Sobrecarga de função é um processo de criar várias funções com o mesmo nome, mas com diferentes parâmetros. Isso significa que em variantes sobrecarregadas de uma função, o número de argumentos e/ou seus tipos devem ser diferentes. Um variante de função específica é selecionada baseada na correspondência entre lista de argumentos ao chamar a função com a lista de parâmetros na declaração da função.

Quando uma função sobrecarregada é chamada, o compilador deve ter uma algoritmo para selecionar a função apropriada. O algoritmo que realiza esta escolha depende da conversão de quais tipos estiverem presentes. A melhor correspondência deve ser única. Uma função sobrecarregada deve ser a melhor correspondência dentre todas as outras variantes para ao menos um argumento. Ao mesmo tempo, ela não deve ser pior que as outras variantes para todos os outros argumentos.

Abaixo está um algoritmo de correspondência para cada argumento.

Algoritmo de Escolha de uma Função Sobrecarregada
Use estrita correspondência (se possível).
Tente incremento de tipo padrão.
Tente conversão de tipo padrão.
O incremento de tipo padrão é melhor que outras conversões padrão. Incremento é a conversão de float para double, de bool, char, short ou enum para int. Conversão de tipo de arrays de tipos inteiros similares também pertencem a conversão de tipo. Tipos similares são: bool, char, uchar, já que todos os três tipo são inteiros de único bytes, inteiros de duplo byte short e ushort; inteiros de 4 bytes int, uint, e color; long, ulong e datetime.

Claro que a estrita correspondência é a melhor. Para alcançar tal consistência conversão de tipo (typecasting) pode ser usada. O compilador não pode lidar com situações ambíguas. Portanto você não deve confiar em diferenças sutis de tipos e conversões implícitas que tornam a função sobrecarregada não clara.

No caso de dúvida, use conversão explícita para assegurar estrita adequação.

Exemplos de funções sobrecarregadas no MQL5 podem ser vistas no exemplo de funções ArrayInitialize().

Regras de sobrecarga de função para sobrecarga de métodos de classe.



A sobrecarga de funções de sistema é permitida, mas deve-se observar que o compilador é capaz de selecionar com precisão a função necessária. Por exemplo, podemos sobrecarregar o sistema da função MathMax() de 4 maneiras diferentes, mas apenas duas variantes são corretas.

Exemplo:

// 1. sobrecarga é permitida - função difere da função embutida MathMax() em número de parâmetros
double MathMax(double a,double b,double c);

// 2. sobrecarga não é permitida!
// número de parâmetros é diferente, mas o último tem um valor default
// isso leva ao ocultamento da função de sistema ao chamar-lo, o que é inaceitável
double MathMax(double a,double b,double c=DBL_MIN);

// 3. sobrecarga é permitida - sobrecarga normal para tipos de parâmetros 'a' e 'b'
double MathMax(int a,int b);

// 4. sobrecarga não é permitida!
// o número e tipos de parâmetros são os mesmos que no original double MathMax (double a,double b)
int MathMax(double a,double b);