Getters et setters
Fait partie de la section Object Oriented Programming du Journey C de Coddy — leçon 19 sur 61.
Avec les pointeurs opaques, les membres de la structure sont cachés du code externe. Mais si le code externe ne peut pas accéder directement aux données, comment pouvons-nous 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 retourne la valeur d'un membre caché :
// 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 caché :
// 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;
}
Remarquez la convention de nommage : préfixez les fonctions avec le nom du type (counter_) pour éviter les conflits et rendre l'API claire. Les getters utilisent des pointeurs const car ils ne modifient pas l'objet.
Désormais, le code externe peut interagir avec les données cachées en toute sécurité :
// 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 modèle vous donne un contrôle total sur la façon dont les données sont accédées — une base sur laquelle nous nous appuierons dans la prochaine leçon lorsque nous ajouterons une logique de validation aux setters.
Défi
FacileConstruisons un module Score qui utilise le modèle de pointeur opaque avec des fonctions getter et setter. Vous allez créer un suivi de score masqué où le code externe ne peut interagir avec les données qu'à travers l'interface publique que vous fournissez.
Vous allez créer trois fichiers :
score.h: Votre interface publique. Déclarez un typeScoreopaque à l'aide d'une déclaration anticipée (pas de corps de struct !). Déclarez ces fonctions :create_score— prend un entier pour les points initiaux et renvoie un pointeur Scorefree_score— prend un pointeur Score et libère la mémoirescore_get_points— un getter qui prend unconst Score *et renvoie les points actuelsscore_set_points— un setter qui prend unScore *et un entier, mettant à jour la valeur des points
SCORE_H.score.c: Définissez la structure réellestruct Scoreavec un seul membre masqué :int points. Implémentez les quatre fonctions. Votre getter doit renvoyer la valeur masquée, et votre setter doit la mettre à jour. Rappelez-vous que les getters utilisent des pointeursconstpuisqu'ils ne modifient pas l'objet.main.c: Démontrez votre module en créant un score, en lisant sa valeur, en la modifiant via le setter, puis en la lisant à nouveau.
Vous recevrez deux entrées : les points initiaux (un entier) et la nouvelle valeur de points (un entier) à définir.
Dans votre fichier principal, créez un Score avec les points initiaux, affichez la valeur actuelle à l'aide du getter, mettez-la à jour à l'aide du setter 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}
FreedPar exemple, avec les entrées 100 et 250, la sortie serait :
Initial: 100
Updated: 250
FreedRemarquez comment main.c ne peut pas accéder directement à points — il doit passer par vos fonctions getter et setter. C'est l'encapsulation en action : vous contrôlez exactement comment les données masquées peuvent être lues et modifiées.
Aide-mémoire
Avec les pointeurs opaques, les membres de la structure sont cachés du code externe. Pour accéder à ces données privées ou les modifier, utilisez des fonctions getter et setter.
Un getter renvoie la valeur d'un membre caché et utilise un pointeur const puisqu'il ne modifie pas l'objet :
// 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 caché :
// 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;
}
Utilisez une convention de nommage avec le nom du type comme préfixe (counter_) pour éviter les conflits et clarifier l'API.
Le code externe interagit avec les données cachées via ces fonctions :
// 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
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;
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Object Oriented Programming
1Bases de la programmation modulaire
Fichiers d'en-têteGardes d'inclusionFichiers sourcesFonctions statiquesRécapitulatif : Calculatrice modulaire4Encapsulation
Concept des pointeurs opaquesDéfinir des structures opaquesGetters et settersValidation dans les settersRécapitulatif : La boîte secrète2Objets et méthodes
Structs comme objetsLe pointeur 'Self'Rigueur du mot-clé constPointeur vs ValeurMéthodes utilitairesRécapitulatif : Point Manager5Projet : Compte bancaire simple
Configuration du projetImplémentation du compte8Polymorphisme
Pointeurs de fonctions dans les structuresSimulation de méthodesLe concept d'interfaceImplémentation d'interfacesItération polymorphiqueRécapitulatif : Greeter11Patrons de conception en C
Patron SingletonPatron FabriquePatron ItérateurRécapitulatif : Logger Factory3Cycle de vie des objets
Pattern de constructeurPattern de destructeurInitialisation sur la pileCopie profondeRécapitulatif : String Wrapper6Héritage par composition
Imbrication de structLa règle du premier membreAccès aux membres parentsUpcastingRécapitulatif : Hiérarchie des formes9Projet : Dessinateur de formes
Aperçu du projetImplémentation du cercle