Accès aux membres parents
Fait partie de la section Object Oriented Programming du Journey C de Coddy — leçon 30 sur 61.
Maintenant que nous comprenons l'imbrication de structures (struct embedding) et la règle du premier membre, concentrons-nous sur l'aspect pratique : comment lire et modifier les données du parent imbriqué à l'intérieur d'une fonction.
Lorsqu'une fonction reçoit une structure Child (ou un pointeur vers celle-ci), l'accès aux membres du parent nécessite de naviguer à travers la structure imbriquée. La syntaxe dépend du fait que vous travaillez avec une valeur ou un pointeur.
typedef struct {
int id;
int score;
} Parent;
typedef struct {
Parent parent;
char grade;
} Child;Avec un pointeur vers Child, utilisez l'opérateur flèche pour atteindre le parent, puis le point pour accéder à ses membres :
void update_score(Child* c, int new_score) {
c->parent.score = new_score; // Flèche puis point
}
void print_info(Child* c) {
printf("ID: %d, Score: %d\n", c->parent.id, c->parent.score);
}Avec une valeur (passée par copie), utilisez des points partout :
void show_id(Child c) {
printf("ID: %d\n", c.parent.id); // Point puis point
}Ce modèle d'accès chaîné — child->parent.member ou child.parent.member — est la manière dont vous interagissez avec les données héritées dans le modèle de composition du C. C'est légèrement plus verbeux qu'un véritable héritage, mais c'est explicite et clair quant à la relation entre les types.
Défi
FacileConstruisons un système de notation des étudiants qui démontre comment accéder et modifier des données à l'intérieur d'une structure imbriquée. Vous allez créer une hiérarchie où un Student contient un Person imbriqué, puis écrire des fonctions qui travaillent avec les données du parent à travers l'enfant.
Vous organiserez votre code sur trois fichiers :
student.h: Définissez votre hiérarchie de structures avec des gardes d'inclusion. Créez une structurePersonavecname(un tableau de caractères de 50 caractères) etage(un entier). Définissez ensuite une structureStudentqui imbriquePersoncomme premier membre et ajoute un champgrade(un entier représentant leur score). Déclarez deux fonctions :set_person_agequi prend unStudent*et une nouvelle valeur d'âge, etprint_studentqui prend unStudent*et affiche toutes les informations.student.c: Implémentez les deux fonctions. Votre fonctionset_person_agedoit modifier l'âge à l'intérieur de la structurePersonimbriquée — c'est ici que vous pratiquerez la syntaxe flèche-puis-point (s->person.age). Votre fonctionprint_studentdoit accéder et afficher tous les champs de la personne imbriquée et de l'étudiant lui-même.main.c: Créez une variableStudentet initialisez tous ses champs. Utilisez ensuiteset_person_agepour mettre à jour l'âge de la personne imbriquée, et appelezprint_studentpour afficher le résultat.
Vous recevrez quatre entrées : le nom de l'étudiant (une chaîne de caractères), son âge initial (un entier), sa note (un entier), et un nouvel âge (un entier à mettre à jour via votre fonction).
Dans votre fichier principal, créez l'étudiant avec les valeurs initiales, puis appelez set_person_age pour changer l'âge par la nouvelle valeur, et enfin appelez print_student pour afficher les informations mises à jour.
Votre sortie devrait ressembler à ceci :
Name: Emma
Age: 21
Grade: 85Où Emma est le nom, 21 est l'âge mis à jour (pas l'âge initial), et 85 est la note. L'apprentissage clé ici est de naviguer à travers la structure imbriquée pour lire et écrire les membres du parent.
Aide-mémoire
Pour accéder aux membres d'une structure parente imbriquée à partir d'une fonction, utilisez une syntaxe d'accès chaînée qui dépend du fait que vous travaillez avec un pointeur ou une valeur.
Avec un pointeur vers la structure enfant, utilisez l'opérateur flèche pour atteindre le parent imbriqué, puis la notation par point pour accéder à ses membres :
void update_score(Child* c, int new_score) {
c->parent.score = new_score; // Flèche puis point
}
void print_info(Child* c) {
printf("ID: %d, Score: %d\n", c->parent.id, c->parent.score);
}Avec une valeur (passée par copie), utilisez la notation par point partout :
void show_id(Child c) {
printf("ID: %d\n", c.parent.id); // Point puis point
}Ce modèle — child->parent.member ou child.parent.member — permet un accès explicite aux données héritées dans le modèle de composition du C.
Essayez vous-même
#include <stdio.h>
#include <string.h>
#include "student.h"
int main() {
char name[50];
int initial_age, grade, new_age;
// Lire les entrées
fgets(name, 50, stdin);
name[strcspn(name, "\n")] = '\0'; // Supprimer le saut de ligne
scanf("%d", &initial_age);
scanf("%d", &grade);
scanf("%d", &new_age);
// TODO: Créer une variable Student
// TODO: Initialiser tous les champs de l'étudiant
// - Copier name vers le name de la person imbriquée en utilisant strcpy
// - Définir l'age de la person imbriquée à initial_age
// - Définir le grade de l'étudiant
// TODO: Appeler set_person_age pour mettre à jour l'age à new_age
// TODO: Appeler print_student pour afficher le résultat
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