Menu
Coddy logo textTech

Conteneur de formes

Fait partie de la section Programmation Orientée Objet du Journey C de Coddy. Leçon 48 sur 61.

challenge icon

Défi

Facile

Faisons 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.h et shape.c : ton interface Shape de base et la fonction process_shape.
  • circle.h et circle.c : ton implémentation de Circle avec son constructeur et le calcul de son aire.
  • rectangle.h et rectangle.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 pointeurs Shape* 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 :

  1. Le nombre de formes à créer
  2. Pour chaque forme : un indicateur de type (c pour un cercle, r pour 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.11

Exemple 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.00

L’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 %c

Sans 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

Entraînez-vous par vous-même : Compilateur C en ligne