Menu
Coddy logo textTech

Pointeurs de fonctions dans les structures

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

Jusqu’à présent, nous avons utilisé des pointeurs de fonction comme variables autonomes ou nous les avons transmis comme arguments. L’étape suivante vers le polymorphisme consiste à intégrer directement un pointeur de fonction dans une structure, ce qui donne à la structure son propre comportement.

Lorsqu’une structure contient un pointeur de fonction, chaque instance peut contenir une fonction différente. Cela signifie que deux objets du même type peuvent se comporter différemment lorsque vous appelez leur pointeur de fonction :

typedef void (*PrintFunc)(const char*);

typedef struct {
    const char* name;
    PrintFunc print;  // Pointeur de fonction en tant que membre
} Printer;

La structure Printer possède désormais deux membres : les données (name) et le comportement (print). Pour l’utiliser, vous devez assign une function au pointer lors de l’initialisation :

void loud_print(const char* msg) {
    printf("!!! %s !!!\n", msg);
}

int main() {
    Printer p;
    p.name = "Alert";
    p.print = loud_print;
    
    p.print("Hello");  // Sortie : !!! Hello !!!
    return 0;
}

Remarquez comment nous appelons la fonction via la structure : p.print("Hello"). Cela ressemble remarquablement à l'appel d'une méthode sur un objet dans d'autres langages. La structure contient à la fois ses données et la fonction qui agit dessus.

Ce modèle constitue le fondement du polymorphisme en C : différentes instances peuvent avoir différentes fonctions assignées, produisant des comportements différents à partir du même type de structure.

challenge icon

Défi

Facile

Construisons un système Notifier qui montre comment les structures peuvent encapsuler leur propre comportement grâce aux pointeurs de fonction.

Vous allez créer deux fichiers pour organiser votre code :

  • notifier.h : définissez un type de pointeur de fonction appelé NotifyFunc qui accepte un paramètre const char* et ne renvoie rien. Définissez ensuite une structure Notifier qui contient un name (un const char*) et un pointeur de fonction notify de type NotifyFunc.
  • main.c : incluez votre en-tête et implémentez deux fonctions de notification :
    • alert_notify : affiche le message au format : [ALERT] message
    • info_notify : affiche le message au format : [INFO] message
    Créez ensuite une instance de Notifier, associez la fonction appropriée en fonction de l'entrée, puis appelez la notification via le pointeur de fonction de la structure.

Votre programme recevra deux entrées : un type de notification (1 pour une alerte, 2 pour une information) et un message à afficher.

En fonction du type, affectez la fonction correspondante au membre notify de votre notificateur, puis appelez-la via la structure pour afficher le message.

Exemple de sortie lorsque le type vaut 1 et que le message est "System starting" :

[ALERT] System starting

Exemple de sortie lorsque le type vaut 2 et que le message est "All systems normal" :

[INFO] All systems normal

N'oubliez pas d'utiliser des gardes d'inclusion dans votre fichier d'en-tête et d'appeler la fonction via le membre de la structure : n.notify(message)

Essayez vous-même

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

// TODO: Implémenter la fonction alert_notify
// Doit afficher : [ALERT] message


// TODO: Implémenter la fonction info_notify
// Doit afficher : [INFO] message


int main() {
    int type;
    char message[256];
    
    // Lire l'entrée
    scanf("%d", &type);
    getchar(); // consommer le saut de ligne
    fgets(message, sizeof(message), stdin);
    
    // Supprimer le saut de ligne final du message s'il est présent
    int len = 0;
    while (message[len] != '\0') len++;
    if (len > 0 && message[len-1] == '\n') message[len-1] = '\0';
    
    // TODO: Créer une instance de Notifier
    
    
    // TODO: Selon le type (1 pour alert, 2 pour info),
    // assigner la fonction appropriée au membre notify du notifier
    
    
    // TODO: Appeler la notification via le pointeur de fonction de la structure
    // Utiliser : n.notify(message)
    
    
    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