Zusammenfassung – Formen-Rechner
Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy — Lektion 63 von 104.
Aufgabe
EinfachLassen Sie uns einen Formenkalkulator erstellen, der alles zusammenführt, was Sie über Polymorphismus gelernt haben. Sie werden eine abstrakte Klasse Shape erstellen und konkrete Formen implementieren, die ihre Fläche und ihren Umfang berechnen, wobei alle über eine gemeinsame Schnittstelle zugänglich sind.
Sie werden Ihren Code über vier Dateien organisieren:
Shape.h: Definieren Sie eine abstrakte KlasseShape, die als Blaupause für alle Formen dient. Ihre Basisklasse sollte Folgendes haben:- Ein geschütztes
std::string nameMitglied, um die Form zu identifizieren - 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: Implementieren Sie eine KlasseCircle, die vonShapeerbt:- Ein privates
double radiusMitglied - Einen Konstruktor, der den Radius entgegennimmt (setzen Sie den Namen auf
"Circle") - Implementieren Sie
area()mit der Formel: 3.14159 * radius * radius - Implementieren Sie
perimeter()mit: 2 * 3.14159 * radius
- Ein privates
Rectangle.h: Implementieren Sie eine KlasseRectangle, die vonShapeerbt:- Private Mitglieder
double widthunddouble height - Einen Konstruktor, der Breite und Höhe entgegennimmt (setzen Sie den Namen auf
"Rectangle") - Implementieren Sie
area()als width * height - Implementieren Sie
perimeter()als 2 * (width + height)
- Private Mitglieder
main.cpp: Lesen Sie vier Eingaben ein (jede in einer separaten Zeile):- Kreisradius (double)
- Rechteckbreite (double)
- Rechteckhöhe (double)
- Zweiter Kreisradius (double)
Erstellen Sie alle drei Formen dynamisch und speichern Sie diese in einem Array von
Shape*Pointern. Durchlaufen Sie das Array in einer Schleife und geben Sie für jede Form ihre Informationen in diesem Format aus:<name>: Area: <area> Perimeter: <perimeter>Geben Sie eine Leerzeile zwischen jeder Form aus. Bereinigen Sie Ihre dynamisch zugewiesenen Objekte, wenn Sie fertig sind.
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.8495Beachten Sie, wie dieselbe printShapeInfo Logik für jeden Formtyp funktioniert — das ist die Stärke des Polymorphismus. Ihr Code verarbeitet Kreise und Rechtecke identisch über das Shape Interface, und jede Form weiß, wie sie ihre eigenen Maße berechnet. Verwenden Sie 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 aus Shape* Pointern 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: Iteriere durch das Array und gib die Informationen jeder Form aus
// Format:
// <name>:
// Area: <area>
// Perimeter: <perimeter>
// (Leerzeile zwischen den Formen, aber nicht nach der letzten)
// TODO: Bereinige die dynamisch allokierten Objekte
// delete shapes[i];
return 0;
}
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienC++ Build & KompilierungHeader-Dateien & QuelldateienNamensräume & GültigkeitsbereicheEinführung in OOP in C++Klassen vs. ObjekteDer 'this'-PointerMethoden (Elementfunktionen)Attribute (Datenelemente)Grundlagen zu Ctors & DtorsRückblick - Einfacher Taschenrechner4Klasseneigenschaften
Instanz- vs. statische MemberGetter und SetterConst-MemberfunktionenMutable-SchlüsselwortStatische Methoden und VariablenFriend-Funktionen & KlassenZusammenfassung - Bankkonto-Manager7Vererbung
Grundlagen der VererbungZugriffsstufen bei VererbungAufrufreihenfolge von Ctor & DtorÜberschreiben von MethodenVirtuelle Funktionen & VTableMehrfachvererbungVirtuelle VererbungRückblick - Mitarbeiter-Hierarchie2Speicherverwaltung
Stack vs. Heap SpeicherZeiger und ReferenzenDynamischer Speicher (new/delete)Smart Pointers in C++RAII in C++Rückblick – Dynamischer Array-Manager5Kapselung
Zugriffsspezifizierer in C++Zugriffsspezifizierer im DetailInformation HidingStruct vs. ClassVerschachtelte & innere KlassenRückblick - Studentenverwaltungssystem8Polymorphie
Kompilierzeit- vs. Laufzeit-PolymorphieFunktionsüberladungVirtuelle Funktionen – WiederholungRein virtuelle FunktionenAbstrakte KlassenInterface-Design in C++Dynamic Casting & RTTIZusammenfassung – Formen-Rechner3Konstruktoren & Destruktoren
StandardkonstruktorParametrisierter KonstruktorKopierkonstruktorVerschiebekonstruktorKonstruktor-InitialisierungslistenDelegierende KonstruktorenDestruktoren im DetailRule of Three / Five / ZeroZusammenfassung - String-Klasse6Operatorüberladung
Einführung in die OperatorüberladungArithmetische OperatorüberladungVergleichsoperatorüberladungStream-OperatorenZuweisungsoperatorüberladungÜberladen der [] und () OperatorenTypumwandlungsoperatorenRückblick - Matrix-Klasse9Templates
FunktionstemplatesKlassentemplatesTemplate-SpezialisierungVariadische TemplatesSFINAE & Type Traits GrundlagenRückblick - Generische Container