Pattern de constructeur
Fait partie de la section Object Oriented Programming du Journey C de Coddy — leçon 12 sur 61.
Dans des langages comme Java ou C++, vous créez des objets en utilisant des constructeurs—des fonctions spéciales qui allouent automatiquement de la mémoire et initialisent les champs. Le C ne possède pas une telle fonctionnalité, mais nous pouvons la simuler avec un motif simple : une fonction create_.
Une fonction constructeur en C fait généralement trois choses : alloue de la mémoire avec malloc, initialise tous les champs avec les valeurs appropriées, et retourne un pointeur vers le nouvel objet :
typedef struct {
char *name;
int age;
} Person;
Person *create_person(const char *name, int age) {
Person *p = malloc(sizeof(Person));
p->name = malloc(strlen(name) + 1);
strcpy(p->name, name);
p->age = age;
return p;
}
La fonction retourne un pointeur car l'objet réside sur le tas (heap), et non sur la pile (stack). Cela signifie qu'il persiste après le retour de la fonction et peut être transmis librement. L'appelant l'utilise comme ceci :
Person *alice = create_person("Alice", 30);
printf("%s is %d years old\n", alice->name, alice->age);
Remarquez comment le constructeur gère tous les détails complexes — l'allocation de la structure, l'allocation d'espace pour la chaîne de caractères et la copie des données. L'appelant fournit simplement les valeurs initiales et reçoit un objet prêt à l'emploi. Cela encapsule la logique de création en un seul endroit, rendant votre code plus propre et moins sujet aux erreurs.
Défi
FacileConstruisons un module Book qui utilise le modèle de constructeur pour créer des objets de type livre sur le tas (heap). Vous allez vous entraîner à écrire une fonction create_ qui gère toute l'allocation de mémoire et l'initialisation, en renvoyant un pointeur prêt à l'emploi.
Vous allez créer trois fichiers :
book.h: Déclarez une structureBookavec deux membres :char *title(un pointeur vers une chaîne de caractères allouée dynamiquement) etint pages. Déclarez également une fonction constructeurcreate_bookqui prend une chaîne de titre et un nombre de pages, puis renvoie un pointeur vers un nouveau Book créé. Utilisez des gardes d'inclusion avec le symboleBOOK_H.book.c: Implémentez la fonctioncreate_book. Votre constructeur doit allouer de la mémoire pour la structure Book elle-même, puis allouer une mémoire séparée pour la chaîne de titre (n'oubliez pas de prendre en compte le terminateur nul), copier le titre dans la nouvelle mémoire, définir le champ pages et renvoyer le pointeur vers le nouveau Book.main.c: Utilisez votre constructeur pour créer un livre et afficher ses informations.
Vous recevrez deux entrées : le titre du livre (une chaîne de caractères) et le nombre de pages (un entier).
Dans votre fichier principal, utilisez create_book pour créer un nouveau livre avec les valeurs fournies, puis affichez ses informations dans ce format :
Title: {title}
Pages: {pages}Par exemple, avec les entrées The C Programming Language et 272, la sortie serait :
Title: The C Programming Language
Pages: 272N'oubliez pas que votre constructeur encapsule toute la logique de création — l'appelant fournit simplement les valeurs initiales et reçoit un objet entièrement initialisé prêt à l'emploi.
Aide-mémoire
Une fonction constructeur en C simule la création d'objets en allouant de la mémoire et en initialisant les champs. Elle suit généralement le modèle de nommage create_.
Une fonction constructeur fait trois choses :
- Alloue de la mémoire avec
malloc - Initialise tous les champs avec les valeurs appropriées
- Retourne un pointeur vers le nouvel objet
Exemple de modèle de constructeur :
typedef struct {
char *name;
int age;
} Person;
Person *create_person(const char *name, int age) {
Person *p = malloc(sizeof(Person));
p->name = malloc(strlen(name) + 1);
strcpy(p->name, name);
p->age = age;
return p;
}
Utilisation du constructeur :
Person *alice = create_person("Alice", 30);
printf("%s is %d years old\n", alice->name, alice->age);
La fonction retourne un pointeur car l'objet réside sur le tas (heap) et persiste après le retour de la fonction. Cela encapsule la logique de création en un seul endroit, rendant le code plus propre et moins sujet aux erreurs.
Essayez vous-même
#include <stdio.h>
#include <stdlib.h>
#include "book.h"
int main() {
char title[256];
int pages;
// Lire l'entrée
fgets(title, sizeof(title), stdin);
// Supprimer le saut de ligne s'il est présent
for (int i = 0; title[i]; i++) {
if (title[i] == '\n') {
title[i] = '\0';
break;
}
}
scanf("%d", &pages);
// TODO : Utiliser create_book pour créer un nouveau livre avec les valeurs fournies
// TODO : Afficher les informations du livre dans le format requis :
// Titre : {title}
// Pages : {pages}
// TODO : N'oubliez pas de libérer la mémoire allouée une fois terminé
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