Menu
Coddy logo textTech

Shape-Container

Teil des Abschnitts Objektorientierte Programmierung der C-Journey von Coddy. Lektion 48 von 61.

challenge icon

Aufgabe

Einfach

Bringen wir das Shape-Drawer-Projekt zu seinem großen Finale! Du wirst einen Shape-Container erstellen, der eine gemischte Sammlung von Circles und Rectangles enthält, und anschließend durch diese iterieren, um die Gesamtfläche zu berechnen – und dabei die wahre Stärke des Polymorphismus demonstrieren.

Aufbauend auf allem, was du bisher erstellt hast, wird dein vollständiges Projekt Folgendes enthalten:

  • shape.h und shape.c: dein grundlegendes Shape-Interface und die Funktion process_shape.
  • circle.h und circle.c: deine Circle-Implementierung mit ihrem Konstruktor und der Flächenberechnung.
  • rectangle.h und rectangle.c: deine Rectangle-Implementierung mit ihrem Konstruktor und der Flächenberechnung.
  • main.c: Hier geschieht die Magie. Du wirst ein Array von Shape*-Zeigern erstellen, das jeden Shape-Typ aufnehmen kann. Fülle es mit einer Mischung aus Circles und Rectangles und durchlaufe anschließend das Array, um die Gesamtfläche aller Shapes zusammen zu berechnen und auszugeben.

Dein Programm erhält die folgenden Eingaben:

  1. Die Anzahl der zu erstellenden Shapes
  2. Für jeden Shape: ein Typindikator (c für Circle, r für Rectangle), gefolgt von dessen Abmessungen

Rufe für jeden Shape in deinem Container draw und area selbst über den Shape*-Zeiger auf (shapes[i]->draw(shapes[i]), shapes[i]->area(shapes[i])) und addiere die Fläche zu einer laufenden Gesamtsumme. Verwende hier nicht process_shape aus shape.c: Die Funktion gibt für jeden Shape eine zusätzliche Area:-Zeile aus, die in der erwarteten Ausgabe nicht enthalten ist. Gib nach der Verarbeitung aller Shapes die Gesamtfläche mit 2 Dezimalstellen im Format Total Area: X.XX aus.

Beispiel mit den Eingaben 3, dann 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

Beispiel mit den Eingaben 2, dann 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

Die wichtigste Erkenntnis ist, dass dein Array Shape*-Zeiger speichert. Es spielt keine Rolle, ob jedes Element tatsächlich ein Circle oder ein Rectangle ist. Wenn du iterierst und über jeden Zeiger draw und area aufrufst, wird automatisch die korrekte Implementierung ausgeführt, abhängig davon, wie der jeweilige Shape erstellt wurde. Das ist Polymorphismus in Aktion: eine Schleife, ein Interface, mehrere Verhaltensweisen.

Denke daran, dass du im Array Zeiger auf die eingebetteten Shape-Member deiner konkreten Shapes speichern musst. Verwende 3.14159 für π bei der Flächenberechnung von Circles.

Wichtig: das Lesen des Shape-Typzeichens: Nachdem du die Anzahl der Shapes mit scanf("%d", &n) eingelesen hast, muss jeder nachfolgende Aufruf zum Lesen des Typzeichens den verbleibenden Zeilenumbruch im Eingabepuffer überspringen. Verwende dafür ein führendes Leerzeichen im Formatstring:

scanf(" %c", &type);  // note the space before %c

Ohne das führende Leerzeichen liest scanf das Zeilenumbruchzeichen, das von der vorherigen Eingabe übrig geblieben ist, anstelle des erwarteten c oder r. Dadurch schlägt die Prüfung des Shape-Typs stillschweigend fehl und es wird keine Ausgabe erzeugt.

Probier es selbst

#include <stdio.h>
#include <stdlib.h>
#include "shape.h"
#include "circle.h"
#include "rectangle.h"

int main() {
    // TODO: Lies die Anzahl der Formen ein
    // TODO: Allokiere Arrays für Kreise, Rechtecke und Shape*-Zeiger
    // TODO: Durchlaufe jede Form, lies ihren Typ und ihre Abmessungen,
    //       erstelle die Form und speichere einen Zeiger auf ihre Basis im shapes-Array
    // TODO: Durchlaufe das shapes-Array, rufe shapes[i]->draw(...) und
    //       shapes[i]->area(...) direkt auf und akkumulieren die Gesamtfläche
    //       (rufe process_shape nicht auf: es gibt eine zusätzliche Area-Zeile aus)
    // TODO: Gib die Gesamtfläche im Format aus: Total Area: X.XX
    // TODO: Gib allokierten Speicher frei
    return 0;
}

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-C-Compiler