Menu
Coddy logo textTech

Getters et setters

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

Avec des pointeurs opaques, les membres de la structure sont masqués du code externe. Mais si le code externe ne peut pas accéder directement aux données, comment les lire ou les modifier ? La réponse réside dans les fonctions getter et setter : des interfaces publiques qui fournissent un accès contrôlé aux données privées.

Un getter renvoie la valeur d’un membre masqué :

// counter.h
int counter_get_value(const Counter *c);

// counter.c
int counter_get_value(const Counter *c) {
    return c->value;
}

Un setter modifie un membre masqué :

// counter.h
void counter_set_value(Counter *c, int new_value);

// counter.c
void counter_set_value(Counter *c, int new_value) {
    c->value = new_value;
}

Remarque la convention de nommage : préfixe les fonctions avec le nom du type (counter_) afin d’éviter les conflits et de rendre l’API claire. Les accesseurs utilisent des pointeurs const puisqu’ils ne modifient pas l’objet.

Désormais, le code externe peut interagir en toute sécurité avec les données masquées :

// main.c
Counter *c = create_counter(10);
printf("%d\n", counter_get_value(c));  // 10
counter_set_value(c, 25);
printf("%d\n", counter_get_value(c));  // 25

Ce pattern vous donne un contrôle total sur la façon dont les données sont accessibles : une base sur laquelle nous nous appuierons dans la prochaine leçon lorsque nous ajouterons une logique de validation aux setters.

challenge icon

Défi

Facile

Construisons un module Score qui utilise le modèle du pointeur opaque avec des fonctions d’accesseur et de mutateur. Vous allez créer un gestionnaire de scores masqué avec lequel le code externe ne pourra interagir qu’au moyen de l’interface publique que vous fournissez.

Vous allez créer trois fichiers :

  • score.h : votre interface publique. Déclarez un type Score opaque à l’aide d’une déclaration anticipée (sans corps de structure !). Déclarez ces fonctions :
    • create_score : prend un entier représentant les points initiaux et renvoie un pointeur vers un Score
    • free_score : prend un pointeur vers un Score et libère la mémoire
    • score_get_points : un accesseur qui prend un const Score * et renvoie le nombre actuel de points
    • score_set_points : un mutateur qui prend un Score * et un entier, puis met à jour la valeur des points
    Utilisez des gardes d’inclusion avec le symbole SCORE_H.
  • score.c : définissez la struct Score réelle avec un seul membre masqué : int points. Implémentez les quatre fonctions. Votre accesseur doit renvoyer la valeur masquée, et votre mutateur doit la mettre à jour. N’oubliez pas que les accesseurs utilisent des pointeurs const, puisqu’ils ne modifient pas l’objet.
  • main.c : démontrez votre module en créant un score, en lisant sa valeur, en la modifiant au moyen du mutateur, puis en la lisant à nouveau.

Vous recevrez deux entrées : les points initiaux (un entier) et la nouvelle valeur des points (un entier à définir).

Dans votre fichier principal, créez un Score avec les points initiaux, affichez la valeur actuelle à l’aide de l’accesseur, mettez-la à jour à l’aide du mutateur avec la nouvelle valeur, affichez la valeur mise à jour, puis libérez le score et affichez une confirmation.

Affichez la sortie dans ce format :

Initial: {points}
Updated: {points}
Freed

Par exemple, avec les entrées 100 et 250, la sortie serait :

Initial: 100
Updated: 250
Freed

Remarquez comment main.c ne peut pas accéder directement à points. Il doit passer par vos fonctions d’accesseur et de mutateur. C’est l’encapsulation en action : vous contrôlez exactement la manière dont les données masquées peuvent être lues et modifiées.

Essayez vous-même

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

int main() {
    int initial_points, new_points;
    scanf("%d", &initial_points);
    scanf("%d", &new_points);
    
    // TODO: Créer un Score avec initial_points
    
    // TODO: Afficher la valeur initiale en utilisant le getter
    // Format : "Initial: {points}"
    
    // TODO: Mettre à jour le score en utilisant le setter avec new_points
    
    // TODO: Afficher la valeur mise à jour en utilisant le getter
    // Format : "Updated: {points}"
    
    // TODO: Libérer le score et afficher "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