Rückblick – Shape-Calculator
Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy. Lektion 63 von 104.
Aufgabe
EinfachErstellen wir einen Formrechner, der alles zusammenführt, was du über Polymorphie gelernt hast. Du erstellst eine abstrakte Shape-Klasse und implementierst konkrete Formen, die ihre Fläche und ihren Umfang berechnen, wobei alles über eine gemeinsame Schnittstelle zugänglich ist.
Du organisierst deinen Code auf vier Dateien verteilt:
Shape.h: Definiere eine abstrakteShape-Klasse, die als Vorlage für alle Formen dient. Deine Basisklasse sollte Folgendes enthalten:- Ein geschütztes
std::string name-Mitglied zur Identifizierung der Form - Einen Konstruktor, der den Namen initialisiert
- Rein virtuelle Methoden
area()undperimeter(), diedoublezurückgeben - Eine
getName()-Methode, die den Namen der Form zurückgibt - Einen virtuellen Destruktor
- Ein geschütztes
Circle.h: Implementiere eineCircle-Klasse, die vonShapeerbt:- Ein privates
double radius-Mitglied - Einen Konstruktor, der den Radius entgegennimmt (setze den Namen auf
"Circle") - Implementiere
area()mit der Formel: 3.14159 * radius * radius - Implementiere
perimeter()mit: 2 * 3.14159 * radius
- Ein privates
Rectangle.h: Implementiere eineRectangle-Klasse, die vonShapeerbt:- Private
double width- unddouble height-Mitglieder - Einen Konstruktor, der width und height entgegennimmt (setze den Namen auf
"Rectangle") - Implementiere
area()als width * height - Implementiere
perimeter()als 2 * (width + height)
- Private
main.cpp: Lies vier Eingaben ein (jeweils in einer eigenen Zeile):- Radius des Kreises (double)
- Breite des Rechtecks (double)
- Höhe des Rechtecks (double)
- Radius des zweiten Kreises (double)
Erstelle alle drei Formen dynamisch und speichere sie in einem Array aus
Shape*-Zeigern. Durchlaufe das Array und gib für jede Form ihre Informationen in diesem Format aus:<name>: Area: <area> Perimeter: <perimeter>Gib zwischen den einzelnen Formen eine Leerzeile aus. Räume deine dynamisch reservierten Objekte auf, wenn du fertig bist.
Zum Beispiel mit den Eingaben 5, 4, 6 und 3:
Circle:
Area: 78.5397
Perimeter: 31.4159
Rectangle:
Area: 24
Perimeter: 20
Circle:
Area: 28.2743
Perimeter: 18.8495Beachte, wie dieselbe printShapeInfo-Logik für jeden Formtyp funktioniert. Das ist die Stärke der Polymorphie. Dein Code verarbeitet Kreise und Rechtecke über die Shape-Schnittstelle auf identische Weise, und jede Form weiß, wie sie ihre eigenen Maße berechnet. Verwende das Schlüsselwort override bei allen überschriebenen Methoden, um korrekte Funktionssignaturen sicherzustellen.
Probier es selbst
#include <iostream>
#include "Shape.h"
#include "Circle.h"
#include "Rectangle.h"
using namespace std;
int main() {
// Eingaben lesen
double circleRadius1, rectWidth, rectHeight, circleRadius2;
cin >> circleRadius1;
cin >> rectWidth;
cin >> rectHeight;
cin >> circleRadius2;
// TODO: Erstelle ein Array von Shape*-Zeigern mit 3 Elementen
// Shape* shapes[3];
// TODO: Erstelle Formen dynamisch und speichere sie im Array
// shapes[0] = new Circle(...);
// shapes[1] = new Rectangle(...);
// shapes[2] = new Circle(...);
// TODO: Durchlaufe das Array und gib die Infos jeder Form aus
// Format:
// <name>:
// Fläche: <area>
// Umfang: <perimeter>
// (Leerzeile zwischen den Formen, aber nicht nach der letzten)
// TODO: Dynamisch allokierte Objekte aufräumen
// delete shapes[i];
return 0;
}
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienC++ Build & KompilierungHeader-Dateien & QuelldateienNamespaces & GültigkeitsbereichEinführung in OOP mit C++Klassen vs. ObjekteDer „this“-ZeigerMethoden (Member-Funktionen)Attribute (Datenmember)Grundlagen zu Ctors & DtorsRückblick – Einfacher Taschenrechner4Klassenattribute
Instanz- vs. statische MemberGetter und SetterConst-MemberfunktionenMutable-SchlüsselwortStatische Methoden und VariablenFriend-Funktionen und -KlassenZusammenfassung – Bankkontoverwaltung7Vererbung
Grundlagen der VererbungZugriffsebenen bei der VererbungAufrufreihenfolge von Ctor & DtorÜberschreiben von MethodenVirtuelle Funktionen & VTableMehrfachvererbungVirtuelle VererbungRückblick – Mitarbeiterhierarchie2Speicherverwaltung
Stack- vs. Heap-SpeicherZeiger und ReferenzenDynamischer Speicher (new/delete)Intelligente Zeiger in C++RAII in C++Rückblick – Dynamischer Array-Manager5Kapselung
Zugriffsbezeichner in C++Zugriffsbezeichner im DetailInformationsverbergungStruct vs. KlasseVerschachtelte und innere KlassenWiederholung – Studierendenverwaltungssystem8Polymorphie
Polymorphie zur Compilezeit vs. LaufzeitFunktionsüberladungVirtuelle Funktionen erneut betrachtetRein virtuelle FunktionenAbstrakte KlassenInterface-Design in C++Dynamic Casting & RTTIRückblick – Shape-Calculator3Konstruktoren & Destruktoren
StandardkonstruktorParametrisierter KonstruktorKopierkonstruktorMove-KonstruktorKonstruktor-InitialisierungslistenDelegierende KonstruktorenDestruktor im DetailDrei-/Fünf-/Null-RegelZusammenfassung – String-Klasse6Operatorüberladung
Einführung in die OperatorüberladungArithmetische OperatorüberladungVergleichsoperatorüberladungStream-OperatorenZuweisungsoperatorüberladungÜberladung der Operatoren [] und ()TypkonvertierungsoperatorenWiederholung – Matrix-Klasse9Templates
FunktionstemplatesKlassen-TemplatesTemplate-SpezialisierungVariadische TemplatesGrundlagen zu SFINAE und Type TraitsRückblick – Generischer ContainerÜbe selbstständig: Online-C++-Compiler