Information Hiding
Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy — Lektion 36 von 104.
Information Hiding geht über die bloße Verwendung von Zugriffsmodifikatoren hinaus. Es ist ein Entwurfsprinzip, bei dem Sie nicht nur Daten, sondern auch die Implementierungsdetails darüber verbergen, wie Ihre Klasse intern funktioniert.
Das Ziel ist es, nur das offenzulegen, was Benutzer Ihrer Klasse wissen müssen, während alles andere verborgen bleibt. Dies ermöglicht es Ihnen, die interne Implementierung zu ändern, ohne den Code zu beeinflussen, der Ihre Klasse verwendet:
class Temperature {
double kelvin; // Interne Darstellung - verborgenes Detail
public:
void setCelsius(double c) {
kelvin = c + 273.15; // Umrechnung 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 (oder müssen nicht wissen), dass die Temperatur intern in Kelvin gespeichert wird. Wenn Sie sich später dazu entscheiden, sie stattdessen in Celsius zu speichern, ändern Sie 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 macht Ihren Code einfacher zu warten. Wenn die internen Details verborgen sind, können Sie Optimierungen oder Refactorings vornehmen, ohne bestehenden Code zu beeinträchtigen, der von Ihrer Klasse abhängt.
Aufgabe
EinfachLassen Sie uns eine Distance-Klasse erstellen, die das Prinzip des Information Hiding (Informationskapselung) demonstriert, indem sie Entfernungen intern in Zentimetern speichert, während sie eine saubere Schnittstelle für die Arbeit mit verschiedenen Einheiten bietet. Benutzer Ihrer 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 am bequemsten ist.
Sie werden zwei Dateien erstellen, um Ihren Code zu organisieren:
Distance.h: Definieren Sie eineDistance-Klasse, die ihre interne Darstellung verbirgt, während sie eine flexible öffentliche Schnittstelle bereitstellt. Speichern Sie die Entfernung intern in Zentimetern (alsdouble) — dies ist Ihr verborgenes Implementierungsdetail. Ihre öffentliche Schnittstelle sollte es Benutzern ermöglichen:- Die Entfernung mit
setMeters(double m),setCentimeters(double cm)odersetKilometers(double km)zu setzen - Die Entfernung mit
getMeters(),getCentimeters()odergetKilometers()abzurufen — alle sollten const-Methoden sein - Zwei Entfernungen mit
add(const Distance& other)zu addieren, was ein neuesDistance-Objekt zurückgibt
Fügen Sie einen Standardkonstruktor hinzu, der die Entfernung mit Null initialisiert. Die Konvertierungslogik sollte in Ihren 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: Demonstrieren Sie, dass Benutzer mit Ihrer Klasse arbeiten können, ohne die interne Darstellung zu kennen. Lesen Sie zwei Entfernungswerte von der Eingabe ein: den ersten in Metern, den zweiten in Kilometern. Dann:- Erstellen Sie ein
Distance-Objekt und setzen Sie es mit dem Meter-Wert - Geben Sie
"In meters: <value> m"aus - Geben Sie
"In centimeters: <value> cm"aus - Geben Sie
"In kilometers: <value> km"aus - Erstellen Sie ein zweites
Distance-Objekt und setzen Sie es mit dem Kilometer-Wert - Addieren Sie die beiden Entfernungen und speichern Sie das Ergebnis
- Geben Sie
"Combined in meters: <value> m"aus
- Erstellen Sie ein
Das Schöne am Information Hiding ist, dass Sie die interne Speicherung später von Zentimetern auf Millimeter (oder etwas anderes) ändern könnten, ohne die Art und Weise zu ändern, wie Benutzer mit Ihrer Klasse interagieren. Die öffentliche Schnittstelle bleibt stabil, selbst wenn sich die Implementierung ändert.
Formatieren Sie alle Ausgabewerte mit zwei Dezimalstellen unter Verwendung von std::fixed und std::setprecision(2) aus <iomanip>. Konvertieren Sie Eingabestrings mit std::stod() in Doubles.
Konvertierungsreferenz: 1 Meter = 100 Zentimeter, 1 Kilometer = 1000 Meter.
Spickzettel
Information Hiding (Geheimnisprinzip) ist ein Entwurfsprinzip, bei dem Sie Implementierungsdetails darüber verbergen, wie Ihre Klasse intern funktioniert, und nur das offenlegen, was die Benutzer wissen müssen.
Dies ermöglicht es Ihnen, die interne Implementierung zu ändern, ohne den Code zu beeinflussen, der Ihre Klasse verwendet:
class Temperature {
double kelvin; // Interne Darstellung - verborgenes 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 wissen nicht (und müssen nicht wissen), dass die Temperatur intern in Kelvin gespeichert wird. Wenn Sie später das Speicherformat ändern, ändert sich nur die private Implementierung – die öffentliche Schnittstelle bleibt unverändert.
Vorteile von Information Hiding:
- Reduziert die Komplexität für Benutzer Ihrer Klasse
- Verhindert den versehentlichen Missbrauch interner Daten
- Macht den Code einfacher zu warten und zu refaktorisieren
- Ermöglicht Optimierungen, ohne bestehenden Code zu beeinträchtigen
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; // Zweiter Wert in Kilometern
// Strings in doubles umwandeln mit std::stod()
double metersValue = stod(metersInput);
double kmValue = stod(kmInput);
// Ausgabeformatierung festlegen
cout << fixed << setprecision(2);
// TODO: Erstes Distance-Objekt erstellen und mit dem Meter-Wert setzen
// TODO: "In meters: <value> m" ausgeben
// TODO: "In centimeters: <value> cm" ausgeben
// TODO: "In kilometers: <value> km" ausgeben
// TODO: Zweites Distance-Objekt erstellen und mit dem Kilometer-Wert setzen
// TODO: Die beiden Distanzen mit der add()-Methode addieren
// TODO: "Combined in meters: <value> m" ausgeben
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 & 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