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.
Défi
FacileConstruisons 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 typeScoreopaque à 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 Scorefree_score: prend un pointeur vers un Score et libère la mémoirescore_get_points: un accesseur qui prend unconst Score *et renvoie le nombre actuel de pointsscore_set_points: un mutateur qui prend unScore *et un entier, puis met à jour la valeur des points
SCORE_H.score.c: définissez lastruct Scoreré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 pointeursconst, 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}
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 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;
}
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
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 cercleImplémentation du rectangleUtilisation polymorpheConteneur de formesEntraînez-vous par vous-même : Compilateur C en ligne