Menu
Coddy logo textTech

Itération polymorphique

Fait partie de la section Programmation Orientée Objet du Journey C de Coddy. Leçon 42 sur 61.

Vous avez appris à créer des interfaces et à les implémenter avec différentes fonctions concrètes. Le véritable avantage apparaît lorsque vous pouvez traiter uniformément une collection d’objets différents : parcourir cette collection et appeler le même pointeur de fonction sur chacun, quel que soit le comportement spécifique qui y est associé.

Imaginez que vous avez un tableau de structures Action, chacune ayant sa propre fonction execute assignée :

typedef void (*ExecuteFunc)(void);

typedef struct {
    const char* name;
    ExecuteFunc execute;
} Action;

void jump(void) { printf("Jumping!\n"); }
void run(void)  { printf("Running!\n"); }
void rest(void) { printf("Resting...\n"); }

Vous pouvez créer un tableau de ces actions, chacune étant associée à une fonction différente, puis les parcourir avec une simple boucle for :

int main() {
    Action actions[3] = {
        { "Jump", jump },
        { "Run", run },
        { "Rest", rest }
    };
    
    for (int i = 0; i < 3; i++) {
        printf("%s: ", actions[i].name);
        actions[i].execute();
    }
    return 0;
}

La boucle ne sait pas et ne se soucie pas de ce que chaque action fait en interne. Elle appelle simplement execute() sur chaque élément.

C’est le polymorphisme en action : le même code gère des objets aux comportements complètement différents. Ajouter un nouveau type d’action ne nécessite aucune modification de la logique d’itération ; il suffit d’ajouter un autre élément au tableau.

challenge icon

Défi

Facile

Construisons un système de gestion de Task qui démontre l’itération polymorphe : le traitement d’une collection d’objets qui partagent une interface commune, mais exécutent des comportements différents.

Vous organiserez votre code sur trois fichiers :

  • task.h : définissez ici votre interface de tâche. Créez un type de pointeur de fonction appelé TaskFunc qui ne prend aucun paramètre et ne renvoie rien. Définissez ensuite une structure Task contenant un name (un const char*) et un pointeur de fonction run de type TaskFunc.
  • task.c : implémentez trois fonctions de tâche différentes représentant différents types de travail :
    • backup_task : affiche Backing up data...
    • cleanup_task : affiche Cleaning up files...
    • report_task : affiche Generating report...
  • main.c : rassemblez tout ici. Créez un tableau de structures Task, chacune étant associée à une fonction de tâche différente. Parcourez ensuite le tableau et exécutez chaque tâche de manière polymorphe : pour chaque tâche, affichez son nom, puis appelez sa fonction run.

Votre programme recevra une seule entrée : le nombre de tâches à exécuter (1, 2 ou 3).

Créez un tableau contenant exactement trois tâches dans cet ordre : une tâche de sauvegarde nommée Backup, une tâche de nettoyage nommée Cleanup et une tâche de rapport nommée Report. En fonction de la valeur d’entrée, parcourez uniquement ce nombre de tâches depuis le début du tableau.

Pour chaque tâche de votre itération, affichez le nom de la tâche suivi de deux-points et d’une espace, puis appelez sa fonction run.

Exemple de sortie lorsque l’entrée est 2 :

Backup: Backing up data...
Cleanup: Cleaning up files...

Exemple de sortie lorsque l’entrée est 3 :

Backup: Backing up data...
Cleanup: Cleaning up files...
Report: Generating report...

L’idée essentielle est que votre boucle n’a pas besoin de savoir ce que fait chaque tâche. Elle affiche simplement le nom et appelle run() sur chaque élément. Le même code d’itération gère uniformément tous les types de tâches. N’oubliez pas d’utiliser des gardes d’inclusion dans votre fichier d’en-tête.

Essayez vous-même

#include <stdio.h>
#include "task.h"

// Déclare les fonctions de tâche implémentées dans task.c
void backup_task(void);
void cleanup_task(void);
void report_task(void);

int main() {
    int count;
    scanf("%d", &count);
    
    // TODO: Créer un tableau de 3 structures Task dans cet ordre :
    // 1. Tâche de sauvegarde nommée "Backup" utilisant backup_task
    // 2. Tâche de nettoyage nommée "Cleanup" utilisant cleanup_task
    // 3. Tâche de rapport nommée "Report" utilisant report_task
    
    // TODO: Parcourir 'count' tâches du tableau
    // Pour chaque tâche, afficher : "<name>: " puis appeler sa fonction run
    
    return 0;
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet

Entraînez-vous par vous-même : Compilateur C en ligne