Surcharge de Fonction

Le nom de la fonction tend normalement à refléter le but principal de la fonction. La règle générale est que les programmes qui sont lisibles contiennent différents identifiants bien sélectionnés. Différentes fonctions sont parfois utilisées pour les mêmes buts. Considérons par exemple une fonction calculant la valeur moyenne d'un tableau de nombres de précision double et la même fonction, mais opérant sur un tableau d'entiers. Il est pratique d'appeler ces deux fonctions AverageFromArray :

//+------------------------------------------------------------------+
//| Calcul d'une moyenne d'un tableau de types doubles               |
//+------------------------------------------------------------------+
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];    // Somme des double
     }
   aver=sum/size;       // Divise la somme par le nombre
//---
   Print("Calcul de la moyenne d'un tableau de doubles");
   return aver;
  }
//+------------------------------------------------------------------+
//| Calcul d'une moyenne d'un tableau de types entiers               |
//+------------------------------------------------------------------+
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];     // Somme des entiers
     }
   aver=(double)sum/size;// Division de la somme par la taille
//---
   Print("Calcul de la moyenne d'un tableau d'entiers");
   return aver;
  }

Chaque fonction émet un message via la fonction Print() ;

   Print("Calcul de la moyenne d'un tableau d'entiers");

Le compilateur sélectionne la fonction nécessaire selon le type des arguments et leur quantité. La règle selon laquelle le choix est effectué est appelée l'algorithme de correspondance des signatures. La signature est la liste de types utilisés dans la déclaration de la fonction.

Exemple :

//+------------------------------------------------------------------+
//| Fonction de lancement du programme                               |
//+------------------------------------------------------------------+
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);
  }
//--- Résultat du script
// Calcule la moyenne d'un tableau de types int
// Calcule la moyenne d'un tableau de types doubles
// int_aver= 3.00000000    double_aver= 3.30000000

La surcharge de fonction est le procédé de création de plusieurs fonctions avec le même nom, mais avec des paramètres différents. Cela signifie que dans les variantes surchargées d'une fonction, le nombre d'arguments et/ou leurs types doivent être différents. Une version spécifique de la fonction est sélectionnée en fonction de la correspondance de la liste des arguments lors de l'appel de la fonction avec la liste des paramètres dans la déclaration de la fonction.

Lorsqu'une fonction surchargée est appelée, le compilateur doit avoir un algorithme pour sélectionner la fonction appropriée. L'algorithme qui effectue ce choix dépend des castings des types présents. La meilleure correspondance doit être unique. Une fonction surchargée doit être la meilleure correspondance parmi toutes les variantes pour au moins un argument. En même temps, tous les autres arguments doivent également correspondre, mais pas de façon moindre que les autres variantes.

Un algorithme de correspondance pour chaque argument est présenté ci-dessous.

Algorithme de Choix d'une Fonction Surchargée

  1. Utilise la correspondante stricte (si possible).
  2. Essaye l'augmentation du type standard.
  3. Essaye le casting de type standard.

L'augmentation du type standard est meilleure que toutes les autres conversions standards. L'augmentation est la conversion de float vers double, de bool, char, short ou enum vers int. Le casting de type des tableaux de types integer similaires appartient également au casting de type. Les types similaires sont : bool, char, uchar, puisque les trois types sont des entiers sur un seul octet ; les entiers sur deux octets short et ushort ; les enties sur 4 octets int, uint et color ; long, ulong et datetime.

La correspondance stricte est bien sûr la meilleure. Pour aboutir à cette consistence, le casting de type peut être utilisé. Le compilateur ne peut pas gérer des situations ambigües. Vous ne devriez donc pas vous fier aux différences subtiles des types et aux conversions implicites qui rendent les fonctions surchargées non claires.

En cas de doute, utilisez une conversion explicite pour assurer une correspondance stricte.

Des exemples de fonctions surchargées en MQL5 sont visibles dans l'exemple des fonctions ArrayInitialize().

Les règles de surcharge des fonctions s'appliquent aux méthodes de classes surchargées.

 

La surcharge des fonctions du système est autorisée mais il est à noter que le compilateur est capable de sélectionner la fonction nécessaire de fonction précise. Par exemple, nous pouvons surcharger la fonction système MathMax() de 4 façons différentes, mais dont seulement deux variantes sont correctes.

Exemple :

// 1. la surcharge est autorisée - la différence avec la fonction MathMax() intégrée est au niveau du nombre de paramètres
double MathMax(double a,double b,double c);
 
// 2. la surcharge n'est pas autorisée !
// le nombre de paramètres est différent, mais le dernier a une valeur par défaut
// cela mène à la dissimulation de la fonction système lors de l'appel, ce qui n'est pas acceptable
double MathMax(double a,double b,double c=DBL_MIN);
 
// 3. la surcharge est autorisée - surcharge normale par le type des paramètres a et b
double MathMax(int a,int b);
 
// 4. la surcharge n'est pas autorisée !
// le nombre et le type des paramètres sont les mêmes que dans la fonction d'origine double MathMax(double a,double b)
int MathMax(double a,double b);

Voir aussi

Surcharge, Fonctions Virtuelles, Polymorphisme