Informationsverbergung
Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy. Lektion 36 von 104.
Informationsverbergung geht über die bloße Verwendung von Zugriffsbezeichnern hinaus. Es handelt sich um ein Designprinzip, bei dem du nicht nur Daten, sondern auch die Implementierungsdetails darüber verbirgst, wie deine Klasse intern funktioniert.
Das Ziel besteht darin, nur das offenzulegen, was Benutzer deiner Klasse wissen müssen, während alles andere verborgen bleibt. Dadurch kannst du die interne Implementierung ändern, ohne den Code zu beeinflussen, der deine Klasse verwendet:
class Temperature {
double kelvin; // Interne Darstellung - verstecktes Detail
public:
void setCelsius(double c) {
kelvin = c + 273.15; // Konvertierung vor dem Benutzer verborgen
}
double getCelsius() const {
return kelvin - 273.15;
}
double getFahrenheit() const {
return (kelvin - 273.15) * 9.0/5.0 + 32;
}
};Benutzer dieser Klasse wissen nicht (und müssen auch nicht wissen), dass die Temperatur intern in Kelvin gespeichert wird. Wenn du dich später entscheidest, sie stattdessen in Celsius zu speichern, änderst du nur die private Implementierung – die öffentliche Schnittstelle bleibt unverändert.
Diese Trennung zwischen Schnittstelle und Implementierung bietet mehrere Vorteile: Sie reduziert die Komplexität für die Benutzer Ihrer Klasse, verhindert den versehentlichen Missbrauch interner Daten und erleichtert die Wartung Ihres Codes. Wenn die internen Details verborgen sind, können Sie optimieren oder umstrukturieren, ohne bestehenden Code zu beschädigen, der von Ihrer Klasse abhängt.
Aufgabe
EinfachErstellen wir eine Distance-Klasse, die das Verbergen von Informationen demonstriert, indem sie Entfernungen intern in Zentimetern speichert und gleichzeitig eine übersichtliche Schnittstelle für die Arbeit mit verschiedenen Einheiten bereitstellt. Benutzer deiner Klasse müssen nicht wissen (oder sich darum kümmern), wie die Entfernung intern gespeichert wird: Sie arbeiten einfach mit der Einheit, die für sie praktisch ist.
Du erstellst zwei Dateien, um deinen Code zu organisieren:
Distance.h: Definiere eineDistance-Klasse, die ihre interne Darstellung verbirgt und gleichzeitig eine flexible öffentliche Schnittstelle bereitstellt. Speichere die Entfernung intern in Zentimetern (alsdouble). Dies ist dein verborgenes Implementierungsdetail. Deine öffentliche Schnittstelle sollte Benutzern Folgendes ermöglichen:- Die Entfernung mit
setMeters(double m),setCentimeters(double cm)odersetKilometers(double km)festzulegen - Die Entfernung mit
getMeters(),getCentimeters()odergetKilometers()abzurufen: Alle Methoden sollten const-Methoden sein - Zwei Entfernungen mit
add(const Distance& other)zu addieren, wobei ein neuesDistance-Objekt zurückgegeben wird
Füge einen Standardkonstruktor ein, der die Entfernung auf null initialisiert. Die Umrechnungslogik sollte innerhalb deiner Methoden verborgen sein: Benutzer rufen einfach
setKilometers(5)undgetMeters()auf, ohne sich um das interne Speicherformat kümmern zu müssen.- Die Entfernung mit
main.cpp: Zeige, dass Benutzer mit deiner Klasse arbeiten können, ohne die interne Darstellung zu kennen. Lies zwei Entfernungswerte aus der Eingabe ein: den ersten in Metern, den zweiten in Kilometern. Anschließend:- Erstelle ein
Distance-Objekt und lege es mithilfe des Meterwerts fest - Gib
"In meters: <value> m"aus - Gib
"In centimeters: <value> cm"aus - Gib
"In kilometers: <value> km"aus - Erstelle ein zweites
Distance-Objekt und lege es mithilfe des Kilometerwerts fest - Addiere die beiden Entfernungen und speichere das Ergebnis
- Gib
"Combined in meters: <value> m"aus
- Erstelle ein
Der Vorteil des Verbergens von Informationen besteht darin, dass du die interne Speicherung später von Zentimetern auf Millimeter (oder etwas anderes) umstellen könntest, ohne die Art und Weise zu ändern, wie Benutzer mit deiner Klasse interagieren. Die öffentliche Schnittstelle bleibt stabil, selbst wenn sich die Implementierung ändert.
Formatiere alle Ausgabewerte mit zwei Nachkommastellen, indem du std::fixed und std::setprecision(2) aus <iomanip> verwendest. Wandle Eingabezeichenfolgen mit std::stod() in Gleitkommazahlen um.
Umrechnungsreferenz: 1 Meter = 100 Zentimeter, 1 Kilometer = 1000 Meter.
Probier es selbst
#include <iostream>
#include <string>
#include <iomanip>
#include "Distance.h"
using namespace std;
int main() {
// Eingabewerte lesen
string metersInput, kmInput;
cin >> metersInput; // Erster Wert in Metern
cin >> kmInput; // Second value in kilometers
// Strings mit std::stod() in Doubles umwandeln
double metersValue = stod(metersInput);
double kmValue = stod(kmInput);
// Ausgabeformatierung festlegen
cout << fixed << setprecision(2);
// TODO: Erstelle das erste Distance-Objekt und setze es mit dem Meterwert
// TODO: Gib "In meters: <value> m" aus
// TODO: Print "In centimeters: <value> cm"
// TODO: Print "In kilometers: <value> km"
// TODO: Erstelle das zweite Distance-Objekt und setze es mit dem Kilometerwert
// TODO: Addiere die beiden Distanzen mit der add()-Methode
// TODO: Print "Combined in meters: <value> m"
return 0;
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
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