Shape-Container
Teil des Abschnitts Object Oriented Programming der C-Journey von Coddy — Lektion 48 von 61.
Aufgabe
EinfachBringen wir das Shape Drawer-Projekt zu seinem krönenden Abschluss! Sie werden einen Form-Container erstellen, der eine gemischte Sammlung von Kreisen und Rechtecken enthält, und diese dann durchlaufen, um die Gesamtfläche zu berechnen – was die wahre Stärke der Polymorphie demonstriert.
Aufbauend auf allem, was Sie bisher erstellt haben, wird Ihr vollständiges Projekt Folgendes umfassen:
shape.hundshape.c: Ihre Basis-Schnittstelle Shape und die Funktionprocess_shape.circle.hundcircle.c: Ihre Circle-Implementierung mit ihrem Konstruktor und der Flächenberechnung.rectangle.hundrectangle.c: Ihre Rectangle-Implementierung mit ihrem Konstruktor und der Flächenberechnung.main.c: Hier passiert die Magie. Sie erstellen ein Array vonShape*-Pointern, das jeden Formtyp aufnehmen kann. Füllen Sie es mit einer Mischung aus Kreisen und Rechtecken und durchlaufen Sie dann das Array in einer Schleife, um die Gesamtfläche aller Formen kombiniert zu berechnen und anzuzeigen.
Ihr Programm erhält die folgenden Eingaben:
- Die Anzahl der zu erstellenden Formen
- Für jede Form: ein Typ-Indikator (
cfür Kreis,rfür Rechteck), gefolgt von seinen Dimensionen
Geben Sie für jede Form in Ihrem Container deren Zeichnungsausgabe aus. Geben Sie nach der Verarbeitung aller Formen 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.11Beispiel 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.00Die entscheidende Erkenntnis ist, dass Ihr Array Shape*-Pointer speichert – es spielt keine Rolle, ob jedes Element tatsächlich ein Circle oder ein Rectangle ist. Wenn Sie iterieren und draw sowie area über jeden Pointer aufrufen, wird automatisch die korrekte Implementierung ausgeführt, basierend darauf, wie jede Form konstruiert wurde. Das ist Polymorphie in Aktion: eine Schleife, eine Schnittstelle, mehrere Verhaltensweisen.
Denken Sie daran, dass Sie Pointer auf die eingebetteten Shape-Member Ihrer konkreten Formen im Array speichern müssen. Verwenden Sie 3.14159 für π in den Kreisflächenberechnungen.
Wichtig – Einlesen des Formtyp-Zeichens: Nach dem Einlesen der Anzahl der Formen mit scanf("%d", &n) muss jeder nachfolgende Aufruf zum Lesen des Typ-Zeichens den verbleibenden Zeilenumbruch im Eingabepuffer überspringen. Verwenden Sie dazu ein führendes Leerzeichen im Formatstring:
scanf(" %c", &type); // beachten Sie das Leerzeichen vor %cOhne das führende Leerzeichen liest scanf das vom vorherigen Input übrig gebliebene Zeilenumbruchzeichen anstelle des beabsichtigten c oder r, was dazu führt, dass Ihre Formtypprüfung lautlos fehlschlägt und 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: Reserviere Speicher für Arrays für Kreise, Rechtecke und Shape*-Pointer
// TODO: Iteriere durch jede Form, lies ihren Typ und ihre Dimensionen ein,
// erstelle die Form und speichere einen Pointer auf ihre Basis im shapes-Array
// TODO: Iteriere durch das shapes-Array, rufe draw für jede Form auf,
// und addiere die Gesamtfläche auf
// TODO: Gib die Gesamtfläche im Format: Total Area: X.XX aus
// TODO: Gib den reservierten Speicher frei
return 0;
}
Alle Lektionen in Object Oriented Programming
1Grundlagen der modularen Programmierung
Header-DateienInclude GuardsQuelldateienStatische FunktionenWiederholung: Modularer Taschenrechner4Kapselung
Konzept der Opaque PointersOpaque Structs definierenGetter und SetterValidierung in SetternRückblick: Die geheime Box2Objekte und Methoden
Structs als ObjekteDer 'Self'-PointerConst-CorrectnessPointer vs. WertHilfsmethodenZusammenfassung: Point Manager5Projekt: Einfaches Bankkonto
Projekt-SetupImplementierung des Kontos3Objekt-Lebenszyklus
Konstruktor-MusterDestruktor-MusterStack-InitialisierungTiefe KopieRückblick: String-Wrapper6Vererbung durch Komposition
Struct-EinbettungDie First-Member-RegelZugriff auf Parent-MemberUpcastingRückblick: Formenhierarchie9Projekt: Formen-Zeichner
ProjektübersichtKreis-Implementierung