Conteneur de formes
Fait partie de la section Programmation Orientée Objet du Journey C de Coddy. Leçon 48 sur 61.
Défi
FacileFaisons de notre projet Shape Drawer un véritable bouquet final ! Tu vas créer un conteneur de formes qui contient une collection mixte de Cercles et de Rectangles, puis parcourir cette collection pour calculer l’aire totale : une démonstration de la véritable puissance du polymorphisme.
En t’appuyant sur tout ce que tu as créé jusqu’à présent, ton projet complet comprendra :
shape.hetshape.c: ton interface Shape de base et la fonctionprocess_shape.circle.hetcircle.c: ton implémentation de Circle avec son constructeur et le calcul de son aire.rectangle.hetrectangle.c: ton implémentation de Rectangle avec son constructeur et le calcul de son aire.main.c: c’est ici que la magie opère. Tu vas créer un tableau de pointeursShape*pouvant contenir n’importe quel type de forme. Remplis-le avec un mélange de Cercles et de Rectangles, puis parcours le tableau pour calculer et afficher l’aire totale de toutes les formes combinées.
Ton programme recevra les entrées suivantes :
- Le nombre de formes à créer
- Pour chaque forme : un indicateur de type (
cpour un cercle,rpour un rectangle) suivi de ses dimensions
Pour chaque forme de ton conteneur, appelle toi-même draw et area via le pointeur Shape* (shapes[i]->draw(shapes[i]), shapes[i]->area(shapes[i])) et ajoute l’aire à un total cumulé. N’utilise pas process_shape de shape.c ici : cette fonction affiche une ligne Area: supplémentaire pour chaque forme, alors que la sortie attendue ne doit pas en contenir. Après avoir traité toutes les formes, affiche l’aire totale avec 2 décimales au format Total Area: X.XX.
Exemple avec les entrées 3, puis c 5.0, r 4.0 3.0, c 2.0 :
Drawing Circle with radius: 5.00
Drawing Rectangle with width: 4.00 and height: 3.00
Drawing Circle with radius: 2.00
Total Area: 103.11Exemple avec les entrées 2, puis r 6.0 4.0, r 3.0 2.0 :
Drawing Rectangle with width: 6.00 and height: 4.00
Drawing Rectangle with width: 3.00 and height: 2.00
Total Area: 30.00L’idée essentielle est que ton tableau stocke des pointeurs Shape*. Il ne se soucie pas de savoir si chaque élément est réellement un Circle ou un Rectangle. Lorsque tu parcours le tableau et appelles draw et area via chaque pointeur, l’implémentation correcte s’exécute automatiquement en fonction de la manière dont chaque forme a été construite. C’est le polymorphisme en action : une boucle, une interface, plusieurs comportements.
N’oublie pas que tu devras stocker dans le tableau des pointeurs vers les membres Shape intégrés à tes formes concrètes. Utilise 3.14159 pour π dans les calculs d’aire des cercles.
Important : lire le caractère indiquant le type de forme : après avoir lu le nombre de formes avec scanf("%d", &n), chaque appel suivant pour lire le caractère de type doit ignorer le saut de ligne restant dans le tampon d’entrée. Utilise un espace au début de la chaîne de format pour cela :
scanf(" %c", &type); // note the space before %cSans l’espace au début, scanf lira le caractère de nouvelle ligne restant de l’entrée précédente au lieu du c ou du r attendu, ce qui fera échouer silencieusement la vérification du type de forme et ne produira aucune sortie.
Essayez vous-même
#include <stdio.h>
#include <stdlib.h>
#include "shape.h"
#include "circle.h"
#include "rectangle.h"
int main() {
// TODO: Lire le nombre de formes
// TODO: Allouer des tableaux pour les cercles, les rectangles et les pointeurs Shape*
// TODO: Parcourir chaque forme, lire son type et ses dimensions,
// créer la forme, et stocker un pointeur vers sa base dans le tableau shapes
// TODO: Parcourir le tableau shapes, appeler shapes[i]->draw(...) et
// shapes[i]->area(...) directement et accumuler l'aire totale
// (ne pas appeler process_shape : il affiche une ligne Area supplémentaire)
// TODO: Afficher l'aire totale au format : Total Area: X.XX
// TODO: Libérer la mémoire allouée
return 0;
}
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