Menu
CoddyTech

Définir des structures opaques

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

Maintenant que tu comprends le concept des pointeurs opaques, voyons comment compléter le modèle. L’en-tête déclare qu’un type existe, mais c’est dans le fichier source que tu définis ce qu’il contient réellement.

Voici la configuration complète. D’abord, l’en-tête avec uniquement la déclaration anticipée :

// counter.h
#ifndef COUNTER_H
#define COUNTER_H

typedef struct Counter Counter;  // Type incomplet

Counter *create_counter(int start);
void free_counter(Counter *c);

#endif

Ensuite, le fichier source contient la définition réelle de la structure :

// counter.c
#include "counter.h"
#include <stdlib.h>

struct Counter {
    int value;      // Caché de l’extérieur !
    int step;
};

Counter *create_counter(int start) {
    Counter *c = malloc(sizeof(Counter));
    c->value = start;
    c->step = 1;
    return c;
}

void free_counter(Counter *c) {
    free(c);
}

Le point essentiel : struct Counter { ... } apparaît uniquement dans le fichier .c. Tout fichier qui inclut counter.h sait que Counter existe, mais ne peut pas voir value ni step. Tenter d’écrire c->value dans main.c provoquerait une erreur du compilateur : les membres sont véritablement invisibles.

Cette séparation est le fondement de l’encapsulation en C. L’étape suivante consiste à fournir un accès contrôlé au moyen de fonctions d’accesseur et de mutateur.

challenge icon

Défi

Facile

Construisons un module Timer qui illustre le modèle du pointeur opaque. Tu vas t’exercer à masquer la définition de la structure dans le fichier source, afin que ses membres internes soient totalement invisibles pour tout code qui utilise ton module.

Tu vas créer trois fichiers :

  • timer.h : il s’agit de ton interface publique. Déclare un type opaque Timer à l’aide d’une simple déclaration anticipée : pas de corps de structure ici ! Déclare aussi deux fonctions : create_timer (qui prend un entier correspondant au nombre de secondes et renvoie un pointeur vers un Timer) et free_timer (qui prend un pointeur vers un Timer et effectue le nettoyage). Utilise des gardes d’inclusion avec le symbole TIMER_H.
  • timer.c : c’est ici que se trouve le secret. Définis la véritable struct Timer avec deux membres cachés : int seconds et int running (utilise 1 pour indiquer que le minuteur fonctionne et 0 pour indiquer qu’il est arrêté). Implémente ton constructeur pour allouer la structure, initialiser seconds avec la valeur fournie et définir running sur 1. Implémente le destructeur pour libérer la mémoire.
  • main.c : utilise ton module Timer pour créer un minuteur et confirmer qu’il a bien été créé. Comme les membres de la structure sont cachés, tu ne peux pas y accéder directement. C’est tout l’intérêt ! Affiche simplement un message confirmant sa création, puis libère le minuteur et affiche un message de nettoyage.

Tu recevras une entrée : le nombre de secondes (un entier) à utiliser pour initialiser le minuteur.

Dans ton fichier principal, crée un minuteur avec la valeur de secondes fournie. Affiche un message de création, puis libère le minuteur et affiche une confirmation.

Affiche la sortie dans ce format :

Timer created
Timer freed

L’idée essentielle, ici, est que main.c peut manipuler des pointeurs vers Timer, mais ne peut pas accéder directement à seconds ou à running. Tenter d’écrire t->seconds dans main.c provoquerait une erreur de compilation, car le corps de la structure est défini uniquement dans timer.c. C’est cela, l’encapsulation : les détails de l’implémentation sont totalement masqués aux utilisateurs de ton module.

Essayez vous-même

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

int main() {
    int seconds;
    scanf("%d", &seconds);
    
    // TODO: Créer un minuteur avec la valeur fournie en secondes
    
    // TODO: Afficher "Timer created"
    
    // TODO: Libérer la mémoire du minuteur
    
    // TODO: Afficher "Timer freed"
    
    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