Le pointeur 'Self'
Fait partie de la section Object Oriented Programming du Journey C de Coddy — leçon 7 sur 61.
Dans les langages orientés objet comme Python ou Java, lorsque vous appelez object.method(), le langage passe automatiquement l'objet lui-même à la méthode. En C, nous devons le faire manuellement en passant un pointeur vers la structure comme premier argument.
Ce pointeur est conventionnellement nommé self (emprunté à Python) ou this (de C++). Il donne à la fonction l'accès aux données de la structure afin qu'elle puisse les lire ou les modifier :
typedef struct {
int health;
} Player;
void player_take_damage(Player *self, int amount) {
self->health -= amount;
}
Le pointeur self est ce qui permet à la fonction d'agir comme une méthode — il sait quel joueur modifier. Sans lui, la fonction n'aurait aucun moyen d'accéder à l'instance spécifique de la struct. Lors de l'appel de cette fonction, vous passez l'adresse de votre struct :
Player hero = {100};
player_take_damage(&hero, 25);
// hero.health est désormais 75
L'utilisation d'un pointeur (plutôt que de passer la structure directement) est essentielle pour la modification. Si vous passiez la structure par valeur, la fonction recevrait une copie, et toutes les modifications seraient perdues au retour de la fonction. Le pointeur garantit que les modifications persistent dans la structure originale.
Défi
FacileConstruisons un module Timer qui suit les secondes écoulées. Vous allez vous entraîner à utiliser le motif du pointeur "self" pour modifier l'état interne d'une structure via des fonctions qui agissent comme des méthodes.
Vous allez créer trois fichiers :
timer.h: Déclarez une structureTimeravec un seul membreint seconds. Déclarez également deux fonctions :timer_tick(prend un pointeur vers Timer et ajoute un nombre spécifié de secondes) ettimer_reset(prend un pointeur vers Timer et remet les secondes à zéro). Utilisez des gardes d'inclusion avec le symboleTIMER_H.timer.c: Implémentez les deux fonctions. La fonctiontimer_tickdoit accepter unTimer *selfet unint amount, puis ajouter le montant aux secondes du minuteur. La fonctiontimer_resetdoit accepter unTimer *selfet mettre ses secondes à zéro.main.c: Créez un Timer, effectuez des opérations dessus et affichez les résultats.
Vous recevrez deux entrées entières : les secondes initiales pour votre minuteur et le montant à ajouter via tick.
Dans votre fichier principal :
- Initialisez un
Timeravec la valeur des secondes initiales - Appelez
timer_tickpour ajouter le montant spécifié - Affichez les secondes actuelles
- Appelez
timer_resetpour réinitialiser le minuteur - Affichez à nouveau les secondes (devrait être 0)
Affichez les résultats dans ce format :
After tick: {seconds}
After reset: {seconds}Par exemple, avec une valeur initiale de 30 et en ajoutant 15 secondes, la sortie serait :
After tick: 45
After reset: 0Aide-mémoire
En C, les fonctions qui opèrent sur des structures ont besoin d'un accès explicite à l'instance de la structure via un paramètre de pointeur, conventionnellement nommé self ou this :
typedef struct {
int health;
} Player;
void player_take_damage(Player *self, int amount) {
self->health -= amount;
}
Le pointeur self permet à la fonction d'accéder aux données de la structure et de les modifier. Lors de l'appel de telles fonctions, passez l'adresse de votre structure :
Player hero = {100};
player_take_damage(&hero, 25);
// hero.health est maintenant 75
L'utilisation d'un pointeur est essentielle pour la modification — le passage par valeur créerait une copie, et les modifications seraient perdues au retour de la fonction. Le pointeur garantit que les modifications persistent dans la structure originale.
Essayez vous-même
#include <stdio.h>
#include "timer.h"
int main() {
int initial_seconds, amount_to_add;
scanf("%d", &initial_seconds);
scanf("%d", &amount_to_add);
// TODO: Créer un Timer et l'initialiser avec initial_seconds
// TODO: Appeler timer_tick pour ajouter amount_to_add secondes
// TODO: Afficher les secondes actuelles au format : "After tick: {seconds}"
// TODO: Appeler timer_reset pour réinitialiser le timer
// TODO: Afficher à nouveau les secondes au format : "After reset: {seconds}"
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