Je découvre l'overloading: génial ! :)

Bonsoir à tous,

Pas de question ici, juste un partage. Je viens de découvrir le concept d'overloading (function overloading). Certainement prosaïque pour vous, sauf peut-être pour quelques modestes comme moi.
Empêtré dans un projet et commençant à me perdre dans l'output j'ai voulu me faire une fonction 'printc' de débuggage 'encapsulant' les Serial.print afin de pouvoir les faire disparaître à volonté à partir d'une seule globale booléenne et ne plus voir que les vrais Serial.print.
(nota: j'ai vu qu'il y a des outils de débuggage dans Arduino 2 mais je n'aime pas Windows 10) -
Bien sûr en bon noob je me suis heurté au problème de conversion interdite des types des arguments. J'ai donc trouvé près d'ici un vieux sujet de 2017 et me voilà sauvé :wink:
Bon si vous avez des suggestions pour bien débuguer, je suis naturellement preneur.

[code]
/*        Fonction de debugging utilisant l'overloading
 selon la booléenne globale bool bDebug:
 valeurs  1/0  1: tous les printc apparaissent // 0: seuls les Serial.print apparaissent
 
 */


bool bDebug=1; // valeurs  1/0  1: tous les printc apparaissent // 0: seuls les Serial.print apparaissent

void setup(){
  Serial.begin(115200);  
}
void printc(String sData){
  if (bDebug){
   Serial.print (sData);
  }
}
void printcln(String sData){
  if (bDebug){
   Serial.println (sData);
  }
}
void printc(int nData){
  if (bDebug){
   Serial.print (nData);
  }
}
void printcln(int nData){
  if (bDebug){
   Serial.println (nData);
  }
}



void loop(){ 
  printc("Overloading");
  printcln(2023);
  printcln("Overloading");
  printc(2023);  
  delay(2000);
}
[/code]

c'est pratique n'est-ce pas ?

vous devriez lire des trucs sur les template, ça permet de générer les fonctions que vous utilisez en adaptant le type pour vous par exemple

template <typename T>
void printc(T data){
  if (bDebug)  Serial.print (data);
}

si vous appelez printc()avec un int ou char * ou une String, ça génère pour vous ces fonctions comme si vous les aviez écrites à la main

pour ce qui est de faire disparaître des print de debug, on utilise souvent des macros

par exemple

#define DEBUG 1    // SET TO 0 OUT TO REMOVE TRACES

#if DEBUG
#define D_SerialBegin(...) Serial.begin(__VA_ARGS__);
#define D_print(...)    Serial.print(__VA_ARGS__)
#define D_write(...)    Serial.print(__VA_ARGS__)
#define D_println(...)  Serial.println(__VA_ARGS__)
#else
#define D_SerialBegin(bauds)
#define D_print(...)
#define D_write(...)
#define D_println(...)
#endif

avec cela vous faites juste des D_print(), D_println() ou D_write() et simplement en jouant sur la valeur de DEBUG (0 ou 1) le code disparait par magie lorsque vous compilez

bonus: ça va marcher si vous faites D_println(123, HEX); ou D_println(123.456, 4); ou encore D_println(F("Salut")); ➜ les variations de la fonction print (nombre de chiffres après la virgule, format, chaîne en mémoire flash etc) sont directement gérés.

1 Like

Merci beaucoup. Je me permettrai de revenir vous embêter si je ne m'en sors pas avec mon serveur commandant mon onduleur solaire :wink: - Mais vous m'aviez déjà conseillé un serveur asynchrone. Je vais devoir m'y mettre je pense.
Bonne fin de semaine à tous :wink:

En fait, ce que vous avez montré n'est pas "overloading" car vous avez créé diverses fonctions avec des noms différents (vous avez fait un "wrapping").
Overloading signifie que la même fonction (c'est-à-dire avec le même nom!) peut accepter des paramètres de différents types et se comporter en conséquence de différentes manières.

Voici un exemple où je overload la fonction "print()", en la définissant plusieurs fois en fonction du paramètre :

void setup() {
  Serial.begin(9600);
  int vInt = 10;
  long vLong = 1234567;
  float vFloat = 10.5;
  char vChar[] = "Message";
  
  print(vInt);
  print(vLong);
  print(vFloat);
  print(vChar);
}

void loop() {
}

void print(int v) {
  Serial.print("Int=");
  Serial.println(v);
}

void print(long v) {
  Serial.print("Long=");
  Serial.println(v);
}

void print(float v) {
  Serial.print("Float=");
  Serial.println(v, 4);
}

void print(char* v) {
  Serial.print("String=\"");
  Serial.print(v);
  Serial.println("\"");
}

Output:

Int=10
Long=1234567
Float=10.5000
String="Message"

PS: Pardonnez-moi si je n'écris pas bien en français mais ce n'est pas ma langue... :wink:

si si il a deux fonctions

void printc(String);
void printc(int);

Oui, désolé, vous avez raison !

On peut surtout appeler ça par son nom qui est la surcharge de procédure :slight_smile:

"Surcharge de fonction" en fait si vous voulez être précis et en français dans le texte :slight_smile:

(en anglais overloaded functions, ou overloads)

Oui tu as raison de rectifier je n'ai pas relu ce que j'ai écris :+1:

Bon en tout cas, quand je remplace les Serial.print par mes princ, ça compile mais ça ne tourne plus. Il s'arrête à la lecture du nom du fichier ino, mais sans erreur visible :frowning: GRRRR !
ess09-2eEssaiReplace-f.zip (12.2 KB)

Ok ouf, 2 jours pour résoudre ce bug, des coquilles, des soucis d'include et aussi avec Serial.print() parenthèses vides - qui n'acceptait pas la transformation (logique).
Je vais étudier les méthodes plus sérieuses proposées par @J-M-L, mais là j'avais envie d'aller jusqu'au bout avec ma trouvaille :wink:
Je vais pouvoir chercher plus facilement une solution pour mon onduleur commandé à distance. Ceci dit la solution est peut-être plus côté hardware électronique.
Bon w.e à tous :wink:
ess13.02p.zip (12.0 KB)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.